Solidity

剛剛我的契約用完了-怎麼辦?

  • July 5, 2022

我剛剛簽完契約,並試圖了解如何。顯然我是個菜鳥,玩火併被燒壞(契約上不應該有大筆錢)。我應該在每筆交易中從我的 EOA 轉移我的資金。我仍然感到震驚和麻木。誰能幫我辨識漏洞?我想超越這個,我必須這樣做。我也很高興就如何總體上改進這份契約提供任何意見,謝謝!

攻擊者使用了他創建的不同合約,他沒有直接呼叫我的合約。日誌顯示從我的契約到他的總金額的批准,向第三個地址的單次轉賬(從我的契約),以及從我的契約到他的批准為 0(日誌按此順序)。

contract arb {
ICurve constant curve = ICurve(0xxxx);
Itest constant test = Itest(0xxxx);
address owner;

   constructor() {
          IERC20 token1 = IERC20(0xxxx);
          IERC20 token2 = IERC20(0xxxx);
          token1.approve(0xxxx, 115792089237316195423570985008687907853269984665640564039457584007913129639935);
          token1.approve(0xxxx, 115792089237316195423570985008687907853269984665640564039457584007913129639935);
          token2.approve(0xxxx, 115792089237316195423570985008687907853269984665640564039457584007913129639935);
          token2.approve(0xxxx, 115792089237316195423570985008687907853269984665640564039457584007913129639935);
          owner = msg.sender;
}

modifier onlyOwner(){
   require(msg.sender == owner, "You know why");
   _;
}

function approve(address token, address spender, uint amount) public returns (bool success){
   IERC20 t = IERC20(token);
   return t.approve(spender, amount);
}
function transfer(address token, uint amount) public onlyOwner returns (bool success){
   IERC20 t = IERC20(token);
   return t.transfer(msg.sender, amount);
}
function arb1(uint amt) public{
   uint amt_out = curve.exchange(0, 1, amt, 0);
   uint amt_out2 = test.xxx1(amt_out, 0);
   require(amt_out2 > amt, "Lost in arb");
}
function arb2(uint amt) public{
   uint amt_out = test.xxx2(amt, 0);
   uint amt_out2 = curve.exchange(1, 0, amt_out, 0);
   require(amt_out2 > amt, "Lost in arb");
}
}

interface IERC20 {
function transfer(address to, uint tokens) external returns (bool success);
function approve(address spender, uint tokens) external returns (bool success);
}

interface ICurve {
function exchange(uint i, uint j, uint dx, uint min_dy) payable external returns (uint dy);
}
interface Itest {
function xxx1(uint in, uint min_out) external returns (uint out);
function xxx2(uint in, uint min_out) external returns (uint out);
}

感謝您的任何幫助。

如果沒有您向我們提供 tx-hash 詳細資訊,就很難找到導致黑客攻擊的確切原因。但我猜你的傳輸函式中沒有任何可重入保護——這可能是你的契約被耗盡的原因。

另一個猜測是您的批准函式將任意合約地址作為輸入而沒有任何健全性檢查。如果攻擊者通過了你的令牌地址並批准了她自己作為一個消費者怎麼辦?一旦批准交易被探勘,他就可以使用 transferFrom 轉移餘額。

如果您不想分享交易細節,請溫柔地使用 以更好地了解真正發生的事情。

黑客通過呼叫 arb.approve 和他的地址的支出者來批准您的合約代幣的支出。當他稱它為 msg.sender 時,它是套利合約。

最後我們有津貼

$$ arb $$$$ hacker $$=uint256 然後他通過批准的token介面簡單地將trasferFrom給自己;

同時將 arb.approve 消費地址作為輸入和公共地址並不是一個好主意。

引用自:https://ethereum.stackexchange.com/questions/131168