Aave LendingPool的withdraw()返回值校验及调用有效性验证问题
结论先行
你当前的写法无法达到预期效果,核心问题出在接口定义与返回值类型两个层面,具体说明如下:
问题1:接口定义限制了返回值获取
Solidity中通过接口调用外部合约时,返回值的解析规则完全由你本地定义的接口决定,和目标合约的实际实现无关。你现在用的IAaveLendingPool接口中withdraw函数没有声明返回值,所以哪怕Aave的实际合约有返回值,你通过这个接口调用时也拿不到任何返回数据,直接把调用结果放到require里首先就会触发编译错误。
问题2:返回值类型不是布尔值
Aave V2的withdraw函数实际返回的是uint256类型的实际取出资产数量,不是布尔值。就算你修改了接口拿到返回值,也不能直接把uint类型的值放到require的条件里,会触发类型不匹配的编译错误。
正确实现方式
- 先修改你的
IAaveLendingPool接口,补上withdraw的返回值声明:
interface IAaveLendingPool { function deposit( address asset, uint256 amount, address onBehalfOf, uint16 referralCode ) external; // 加上returns (uint256)声明 function withdraw( address asset, uint256 amount, address to ) external returns (uint256); function getReservesList() external view returns (address[] memory); }
- 调用时校验实际取出金额是否等于你预期的金额:
///@notice assigns dai to caller uint256 actualWithdrawn = aaveLendingPool.withdraw( address(dai), amount, msg.sender ); require(actualWithdrawn == amount, "Error, contract does not have enough DAI");
补充说明
如果withdraw调用过程中出现池子暂停、资产不在白名单等异常场景,交易会直接回滚,不需要额外判断。返回值的校验主要是针对你申请提取的金额超过你可提取额度的场景:这种情况下Aave不会直接回滚交易,只会返回你实际能提取的最大金额,所以需要通过对比返回值和预期值来确认提取是否完全符合预期。
Solidity官方规则中明确规定:外部函数调用的返回值解析完全依赖调用时使用的接口/函数签名定义,与目标合约的实际实现无关,接口定义与实际返回值不匹配会导致返回值解析错误。
内容的提问来源于stack exchange,提问作者parseb
相关产品推荐
相关产品推荐

