實作做一個簡單的SWAP智能合約

Uniswap,Sushiswap,Pancakswap…xxswap,2020年開始各大AMM百家爭鳴,幣圈玩家透過各式swap進行換幣,進一步玩質押挖礦、借貸、彩池等DeFi活動,而撇除流動性設計,其實一個換幣(Swap)合約是很容易的,簡單幾個function就可以完成了,本文將以5分鐘教你簡單部署swap合約。

在開始之前,必須要有的先備知識是「ERC20標準」。ERC20標準是經過社群通過且Openzepplin驗證通過公開發佈的代幣標準,除了標準的需具備Token name,Token symbol,Totalsupply和Decimal外,也有標準function:balancesOf,transfer,allowance,approve,transferFrom(後期加入mint,burn)。

其中:

transfer(address recipient,uint amount):msg.sender把amount數量ERC20代幣發給recipient

approve(address spender,uint amount):msg.sender授權spender可以動用自己amount數涼代幣

transferFrom(address sender,address recipient,uint amount):獲得approve的地址可以指定授權者(sender)把代幣發給recipient

allowance(address owner,address spender):可查看兩個地址間的授權代幣使用數量

接下來,就來開始寫合約吧:

interface ERC20{

function totalSupply()external view returns (uint256);
function balanceOf(address account)external view returns (uint256); function transfer(address recipient,uint256 amount)external returns (bool);
function allowance(address owner,address spender)external returns (uint256);
function approve(address spender,uint256 amount)external returns (bool);
function transferFrom(address sender,address recipient,uint256 amount)external returns (bool);
event Transfer(address indexed from,address indexed to,uint256 value);
event Approve(address indexed owner,address indexed spender,uint256 value);
}

2.接著直接進入主合約,constructor 放入兩個幣種地址(address _token1,address _token2)並先宣告兩個ERC20。

ERC20 public token1;ERC20 public token2;constructor(address _token1,address _token2)public{token1=ERC20(_token1);token2=ERC20(_token2);}

3.把一個交易對(兩個代幣)建立好後,就可以開始寫swap function了。首先我們引入ERC20的_safeTransferFrom,因為實際執行時我們不會直接用到這個function,所以用private function。

function _safeTransferFrom(ERC20 token,address sender,address recipient,uint amount)private{bool sent=token.transferFrom(sender,recipient,amount);require(sent,”Token transfer failed”);}

4.就快完成了,接下來就是最重要的swap function了,首先input包含 _amount1,_amount2,owner1,owner2,owner1轉_amount1數量的token1給owner2,owner2轉_amount2數量的token2給owner1。

接著寫三個require:

第一個是判定呼叫swap的人不是owner1就是owne2

第二個跟第三個是確保兩個owner要swap的兩種token數量都有超過他們approve給swap合約的數量。

接著執行兩個_safeTransferFrom,一個是owner1轉token1給owner2,另一個使owner2轉token2給owner1。

function swap
(uint _amount1,uint _amount2,address owner1,address owner2)
public
{
require(msg.sender==owner1 || msg.sender==owner2,”Not authorized”); require(token1.allowance(owner1,address(this))>=_amount1,”token1 allowance to low”); require(token2.allowance(owner2,address(this))>=_amount1,”token2 allowance to low”); /* transfer tokens */ _safeTransferFrom(token1,owner1,owner2,_amount1); _safeTransferFrom(token2,owner2,owner1,_amount2);
}

大功告成。

測試:

constructor() public ERC20Detailed(“TEST TOKEN”, “TEST”, 6){ _mint(msg.sender, 31000000 * 10 ** 18); }
//"TEST TOKEN"改成自己想要的token name,"TEST"是token symbol,6是Decimal,下面的31000000 * 10 ** 18是發行總量

以上就是簡單的swap合約,如果是要做合約跟owner swap的話只要稍微修改一下就可以了,大家可以自己試試看。(https://github.com/timmychien/solidity/blob/master/swap.sol)