1Do App
Flash Loan
无需把资产迁移到共享池;借出、回调、归还和费用分配全部在钱包 Runtime 的同一交易中完成。
流动性模型
Flash Loan 在钱包地址的 delegatecall 上下文中读取余额,因此某个 Token 的可借上限就是该钱包当时持有的完整 ERC-20 余额。应用没有独立资金池,也不会要求用户先存款。
当前版本没有逐 Token 白名单、单笔额度上限或钱包自定义费率。启用应用后,任何兼容 ERC-20 的现有余额都可能被外部调用者请求用于闪电贷,但必须在同一交易内按规则归还。
interface IERC3156FlashBorrower {
function onFlashLoan(
address initiator,
address token,
uint256 amount,
uint256 fee,
bytes calldata data
) external returns (bytes32);
}
interface IERC3156FlashLender {
function maxFlashLoan(address token) external view returns (uint256);
function flashFee(address token, uint256 amount) external view returns (uint256);
function flashLoan(
IERC3156FlashBorrower receiver,
address token,
uint256 amount,
bytes calldata data
) external returns (bool);
}
interface IFlashLoanApp is IERC3156FlashLender {
function earnings(address token) external view returns (uint256);
function onedoFeeReceiver() external view returns (address);
}原子借款流程
记录余额
应用记录贷款前的钱包 Token 余额,并拒绝零金额或超过当前余额的请求。
转出并回调
应用把 amount 转给 receiver,再调用 onFlashLoan(initiator, token, amount, fee, data)。
借款人主动归还
receiver 必须在回调结束前把本金与费用主动转回钱包,并返回 ERC-3156 规定的 magic value。
检查并分配费用
回调后余额必须至少达到 balanceBefore + fee;随后 1Do 份额转给 fee receiver,钱包份额留在钱包。
费率与收益记账
flashFee 使用整数向下取整。极小金额的 fee 可能为 0;1Do 份额也会再次向下取整。
flashFee 的 token 参数不参与费率计算;当前所有 ERC-20 都使用同一固定公式。
earnings(token) 是钱包历次 Flash Loan 所得份额的累计记账,不是单独锁定、待领取的资金池。收益在结算时已经留在钱包,之后可能被钱包正常花费,所以 earnings 不保证等于当前 Token 余额。
flash fee = floor(amount × 5 / 10,000) // 0.05%
1Do share = floor(flash fee × 1,000 / 10,000) // fee 的 10%
wallet share = flash fee - 1Do share借款人集成
- initiator 是调用 flashLoan 的地址,receiver 是接收资产和回调的合约,两者可以不同。
- 当前实现不会在回调后通过 transferFrom 拉取还款。只做 approve、等待 lender 拉款的通用 borrower 需要适配为主动转账。
- onFlashLoan 必须返回 keccak256("ERC3156FlashBorrower.onFlashLoan");返回其他值会整体回滚。
- 调用目标是启用该应用的钱包地址,并通过 executeRuntimeApp 进入应用。直接调用共享 logic 地址不会读取用户钱包余额或状态。
状态读取与事件
- maxFlashLoan、flashFee 与 earnings 应在目标钱包的 Runtime 上下文读取;eth_call 可调用 executeRuntimeApp 后解码返回 bytes。
- FlashLoanExecuted 记录 initiator、receiver、token、amount、fee 与 onedoFee。由于 delegatecall,事件 emitter 是提供流动性的用户钱包。
- onedoFeeReceiver 固定在当前应用 logic 部署中,不是每个钱包独立配置。升级到新 logic 可能对应新的部署参数。
失败与资产边界
- 金额为零、流动性不足、回调值错误、回调后余额不足或任一 Token 转账失败,都会使整笔交易回滚。
- 借款回调期间仍处于同一个 Runtime 执行锁中,不能嵌套启动另一次 Runtime app 执行。
- 当前只支持 ERC-20,不支持原生币或 NFT 闪电贷。
- fee-on-transfer、rebasing 与其他非标准 ERC-20 没有专门适配,余额增量检查可能使其无法按预期工作。
启用即开放当前余额
Flash Loan 不会预留一部分专用资金。只要应用保持启用且 Registry 允许,外部调用者就可以请求钱包某个 ERC-20 的当前完整余额;钱包应根据自身流动性用途决定是否启用。