NFTFi合约分析
https://github.com/aichitutu/nftfi_study 代码我梳理了一下,方便索引和跳转
v1版本
合约地址 0x88341d1a8F672D2780C8dC725902AAe72F143B0c
一、NFT借贷流程
二、合约分析
(基于solidity ^0.5.16)
2.1 ERC721
ERC721 是由Dieter Shirley 在2017年9月提出。Dieter Shirley 正是加密猫CryptoKitties背后的公司Axiom Zen的技术总监。加密猫也是第一个实现了ERC721 标准的去中心化应用。
ERC-721 Token是独一无二、不可分割、不可互换的,所以它适用于那些具有稀缺性或者不可替换的资源的场景。
approve(address to, uint256 tokenId)
- 授予地址 to 具有 tokenId 的控制权,
- 方法成功后会触发Approval 事件,emit Approval(owner, to, tokenId)
setApprovalForAll(address to, bool approved)
- 授予地址_operator具有所有NFTs的控制权,
- 成功后会触发ApprovalForAll事件,emit ApprovalForAll(msg.sender, to, approved)
2.2 ERC20
ERC-20是一项以太坊代币标准,是从EIP-20提案经过以太坊社区不断讨论验证后通过而来的,是由Vitalik Buterin于2015年提出,是以太坊的第20号代币标准。
approve(address spender, uint256 value)
- msg.sender委托spender转移value个ERC20 token
2.3 NFTfi
2.3.1 合约结构
2.3.2 事件
2.3.3 储存的值
- totalNumLoans 总的贷款数目
- totalActiveLoans 当前未偿还的贷款数目
- mapping (uint256 => Loan) public loanIdToLoan 贷款ID到贷款数据的映射
- mapping (uint256 => bool) public loanRepaidOrLiquidated 贷款是否偿还或结清
- mapping (address => mapping (uint256 => bool)) private _nonceHasBeenUsedForUser 用户离线签名使用的nonce是否使用过
- maximumLoanDuration = 53 weeks 最大的借贷时长为53周
- maximumNumberOfActiveLoans = 2000 该平台允许的最大活跃借贷笔数为2000
- adminFeeInBasisPoints = 500 管理员收取的费用占万分之500
2.3.4 函数
beginLoan
当借方同意贷款条件时调用这个函数开始贷款
payBackLoan
借方还款时调用该函数
liquidateOverdueLoan
当贷款到期且未偿还时,贷方调用该函数得到质押的NFT
cancelLoanCommitmentBeforeLoanHasBegun
借方或贷方取消包含该nonce的交易
getPayoffAmount
入参:uint256 _loanId
用于计算借方目前需要偿还贷款的金额
getWhetherNonceHasBeenUsedForUser
入参:address _user, uint256 _nonce
检查_user是否使用过_nonce
V2版本
合约地址 0xf896527c49b44aAb3Cf22aE356Fa3AF8E331F280
新的机制
- 借方可设置,当贷方给出的条件合适时,借方自动接单
- v2为固定贷款,即无论是否提前还款,都要归还最终的偿还金额
- 合伙人机制
- 推荐人机制
- 为借方提供了通过闪电贷领取空投的功能(例如利用闪电贷领取APE空投如何用闪电贷领取$APE空投_哔哩哔哩_bilibili)
一、NFT借贷流程
- V1版本仅能由借方startLoan,而V2版本双方都可以,但是合约中并没有acceptListing方法,可能由前端实现,当借方设置自动下单时,贷方可调用accepteListing,待研究
- V2版本给借方新增了一个ERC721格式的债务收据
二、合约分析
(基于solidity 0.8.4)
2.1 合约结构
2.2 事件
- 橙色为V2新增的
|事件|触发时机|参数| | :- | :- | :- | |AdminFeeUpdated|管理员更新其收益率时触发|newAdminFee 新的管理员收益率| |MaximumLoanDurationUpdated|管理员更新最大贷款时长时触发|newMaximumLoanDuration 新的最大贷款时长| |LoanStarted|开始贷款时触发|loanId 贷款的唯一IDborrower 借方地址Lender 贷方地址loanTerms 贷款条款loanExtras 贷款附加条款| |LoanRepaid|偿还贷款时触发|loanId 贷款的唯一IDBorrower 借方地址Lender 贷方地址loanPrincipalAmount 本金数额nftCollateralId NFT抵押品的IDamountPaidToLender 付给贷方的数额adminFee 给管理员的费用revenueShare 管理员从合伙人收益中得到的金额revenueSharePartner 分享收益的合伙人地址nftCollateralContract nft的合约loanERC20Denomination ERC20代币的地址| |LoanLiquidated|清算贷款时触发|loanId 贷款的唯一IDborrower 借方的地址lender 贷方的地址loanPrincipalAmount 本金数额nftCollateralId NFT抵押品的tokenIDloanMaturityDate 贷款到期时间unix timeloanLiquidationDate 贷款结清的时间nftCollateralContract NFT抵押品的合约地址| |LoanRenegotiated|重新协商某些条款时触发|loanId 贷方的唯一IDborrower 借方的地址lender 贷方的地址newLoanDuration 新的贷款时长newMaximumRepaymentAmount 新的最大偿还金额renegotiationFee 协商费renegotiationAdminFee 协商的管理员费| |ERC20Permit|当管理员设置新的ERC20代币时触发|erc20Contract 代币合约地址isPermitted 是否允许| |AirdropPulledFlashloan|当启用闪电贷领取空投时触发|loanId 贷款的唯一IDborrower 借方的地址nftCollateralId NFT抵押品的tokenidnftCollateralContract NFT抵押品的合约target 空投合约地址data 调用空投合约中的函数| |CollateralWrapped|当抵押的NFT被封装在空投接收器中触发|loanId 贷款的唯一IDborrower 借方地址nftCollateralId NFT抵押品的tokenidnftCollateralContract NFT抵押品的合约receiverId 接收者的IDreceiverInstance 空投接收器的地址|
2.3 函数
acceptOffer
pullAirdrop
通过闪电贷从目标合约领取空投
WrapCollateral
将质押中的NFT替换为代理合约上的wrapped NFT,并标记借方为空投受益人。
。。。
2.4 可能的风险
wrapCollateral函数~~是任何人都能调用~~借方调用的的,其入参loanId也是公开的,作用是将质押中的NFT替换为代理合约上的wrapped NFT,并标记借方为空投受益人。
然后owner调用drainERC721Airdrop便可以取走质押中的NFT。