Revest Finance 重入攻击分析

攻击交易:
https://etherscan.io/tx/0xe0b0c2672b760bef4e2851e91c69c8c0ad135c6987bbf1f43f5846d89e691428
合约代码:
Revest:https://etherscan.io/address/0x2320a28f52334d62622cc2eafa15de55f9987ed9#code
TokenVault:https://etherscan.io/address/0xA81bd16Aa6F6B25e66965A2f842e9C806c0AA11F#code
FNFTHandler:https://etherscan.io/address/0xe952bda8c06481506e4731C4f54CeD2d4ab81659#code


合约FNFTHandler中mint函数mint后将fnftsCreated 增加,而_mint中存在回调确认函数.

function mint(address account, uint id, uint amount, bytes memory data) external override onlyRevestController {
    
    
        supply[id] += amount;
        _mint(account, id, amount, data);
        fnftsCreated += 1;
    }
function _mint(
        address account,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
    
    
        require(account != address(0), "ERC1155: mint to the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);

        _balances[id][account] += amount;
        emit TransferSingle(operator, address(0), account, id, amount);

        _doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);
    }

同时合约Revest中仅有withdrawFNFT可以防重入,即允许重复创建同一个fnftId,并且因为supply[id] += amount,nft数量多次创建不会重置,但可以更改相同fnftId的nft的属性;


攻击者调用mintAddressLock函数铸造了2个ID为1027的Token,
随后再次调用mintAddressLock铸造了360000个ID为1028的Token,在mint函数回调中重入调用depositAdditionalToFNFT函数,质押1027并mint一个1028并修改1028对应的fnft.depositAmount(fnftsCreated在mint之后更新)
最后调用withdrawFNFT提取360001个1028中的depositAmount的对应代币.完成攻击

猜你喜欢

转载自blog.csdn.net/Timmbe/article/details/124581227