Prepared by:
HALBORN
Last Updated 04/26/2024
Date of Engagement by: March 7th, 2022 - March 25th, 2022
100% of all REPORTED Findings have been addressed
All findings
1
Critical
0
High
0
Medium
0
Low
0
Informational
1
\client engaged Halborn to conduct a security audit on their smart contracts beginning on 2022-03-07 and ending on 2022-03-25. The security assessment was scoped to the smart contracts provided to the Halborn team.
The team at Halborn was provided two weeks for the engagement and assigned a full-time security engineer to audit the security of the smart contract. The security engineer is a blockchain and smart-contract security expert with advanced penetration testing, smart-contract hacking, and deep knowledge of multiple blockchain protocols.
The purpose of this audit is to:
Ensure that smart contract functions operate as intended
Identify potential security issues with the smart contracts
In summary, Halborn identified a security risk that was acknowledged by the \client team.
Halborn performed a combination of manual and automated security testing to balance efficiency, timeliness, practicality, and accuracy in regard to the scope of this audit. While manual testing is recommended to uncover flaws in logic, process, and implementation; automated testing techniques help enhance coverage of the NFTfi develop-v2.1-audit branch and Pool V5 contract solidity code and can quickly identify items that do not follow security best practices. The following phases and associated tools were used throughout the term of the audit:
Research into architecture and purpose.
Smart contract manual code review and walkthrough.
Graphing out functionality and contract logic/connectivity/functions (solgraph
)
Manual assessment of use and safety for the critical Solidity variables and functions in scope to identify any arithmetic related vulnerability classes.
Manual testing by custom scripts.
Scanning of solidity files for vulnerabilities, security hotspots or bugs. (MythX
)
Static Analysis of security for scoped contract, and imported functions. (Slither
)
Testnet deployment (Remix IDE
)
IN-SCOPE : NFTfi v2.2-07-03-2022-audit branch contracts
The security assessment was scoped to the following smart contract: Scope-Commit-Id : 77d8476ff40e048dcca108265e863a3ebdfb261a
Remediation Commit-Id : dedc4aca9d79a4eb63c507e37916bd70c5d0e9f5
contracts/NftfiHub.sol
contracts/airdrop/AirdropFlashLoan.sol
contracts/airdrop/AirdropReceiver.sol
contracts/airdrop/AirdropReceiverFactory.sol
contracts/airdrop/IAirdropReceiverFactory.sol
contracts/composable/ERC9981155Extension.sol
contracts/composable/ERC998ERC20Extension.sol
contracts/composable/ERC998TopDown.sol
contracts/composable/NftfiBundler.sol
contracts/interfaces/*.sol
contracts/loans/BaseLoan.sol
contracts/loans/direct/DirectLoanCoordinator.sol
contracts/loans/direct/loanTypes/DirectLoanBaseMinimal.sol
contracts/loans/direct/loanTypes/DirectLoanFixedOffer.sol
contracts/loans/direct/loanTypes/IDirectLoanBase.sol
contracts/loans/direct/loanTypes/LoanAirdropUtils.sol
contracts/loans/direct/loanTypes/LoanChecksAndCalculations.sol
contracts/loans/direct/loanTypes/LoanData.sol
contracts/nftTypeRegistry/nftTypes/CryptoKittiesWrapper.sol
contracts/nftTypeRegistry/nftTypes/ERC1155Wrapper.sol
contracts/nftTypeRegistry/nftTypes/ERC721Wrapper.sol
contracts/permittedLists/PermittedAirdrops.sol
contracts/permittedLists/PermittedERC20s.sol
contracts/permittedLists/PermittedNFTsAndTypeRegistry.sol
contracts/permittedLists/PermittedPartners.sol
contracts/smartNft/SmartNft.sol
contracts/utils/ContractKeys.sol
contracts/utils/NFTfiSigningUtils.sol
contracts/utils/NFTfiSigningUtilsContract.sol
contracts/utils/NftReceiver.sol
contracts/utils/Ownable.sol
contracts/utils/TokenTrade.sol
Additions 31st March 2022:
contracts/loans/direct/loanTypes/DirectLoanBaseBundle.sol
contracts/loans/direct/loanTypes/DirectLoanFixedListing.sol
contracts/loans/direct/loanTypes/DirectLoanProRatedOffer.sol
contracts/loans/direct/loanTypes/DirectLoanProRatedListing.sol
contracts/loans/direct/loanTypes/DirectLoanFixedBundleOffer.sol
contracts/loans/direct/loanTypes/DirectLoanFixedBundleListing.sol
contracts/loans/direct/loanTypes/DirectLoanProRatedBundleListing.sol
contracts/loans/direct/loanTypes/DirectLoanProRatedBundleOffer.sol
Critical
0
High
0
Medium
0
Low
0
Informational
1
Impact x Likelihood
HAL-01
Security analysis | Risk level | Remediation Date |
---|---|---|
CAUSE-EFFECT CHECKS | Informational | Acknowledged |
// Informational
The _payBackLoan
under DirectLoanBaseMinimal
does not pre-check the user's balance by being payoffAmount + adminFee + revenueShare
it does so incrementally.
ACKNOWLEDGED: The NFTfi team
acknowledged this issue.
digraph G {
graph [ ratio = "auto", page = "100", compound =true, bgcolor = "#2e3e56" ];
node [ style = "filled", fillcolor = "#edad56", color = "#edad56", penwidth =3 ];
edge [ color = "#fcfcfc", penwidth =2, fontname = "helvetica Neue Ultra Light" ];
subgraph "clusterAirdropFlashLoan" {
graph [ label = "AirdropFlashLoan", color = "#445773", fontcolor = "#f0f0f0", style = "rounded", bgcolor = "#445773" ];
"AirdropFlashLoan.<Constructor>" [ label = "<Constructor>", color = "#FF9797", fillcolor = "#FF9797" ];
"AirdropFlashLoan.pullAirdrop" [ label = "pullAirdrop", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"AirdropFlashLoan.supportsInterface" [ label = "supportsInterface", color = "#FF9797", fillcolor = "#FF9797" ];
"AirdropFlashLoan._transferNFT" [ label = "_transferNFT" ];
"AirdropFlashLoan._getSelector" [ label = "_getSelector" ];
"AirdropFlashLoan.INftfiHub" [ label = "INftfiHub" ];
"AirdropFlashLoan.IPermittedAirdrops" [ label = "IPermittedAirdrops" ];
"AirdropFlashLoan.IERC1155" [ label = "IERC1155" ];
"AirdropFlashLoan.IERC721" [ label = "IERC721" ];
"AirdropFlashLoan.type" [ label = "type" ];
"AirdropFlashLoan.INftWrapper" [ label = "INftWrapper" ];
}
subgraph "clusterINftfiHub" {
graph [ label = "INftfiHub", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"INftfiHub.getContract" [ label = "getContract" ];
}
subgraph "cluster_target" {
graph [ label = "_target", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"_target.functionCall" [ label = "functionCall" ];
}
subgraph "clusterReentrancyGuard" {
graph [ label = "ReentrancyGuard", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"ReentrancyGuard.supportsInterface" [ label = "supportsInterface" ];
}
subgraph "cluster_nftWrapper" {
graph [ label = "_nftWrapper", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"_nftWrapper.functionDelegateCall" [ label = "functionDelegateCall" ];
}
"AirdropFlashLoan.<Constructor>";
"AirdropFlashLoan.INftfiHub";
"AirdropFlashLoan.pullAirdrop";
"AirdropFlashLoan.IPermittedAirdrops";
"INftfiHub.getContract";
"AirdropFlashLoan._getSelector";
"_target.functionCall";
"AirdropFlashLoan._transferNFT";
"AirdropFlashLoan.IERC1155";
"AirdropFlashLoan.IERC721";
"AirdropFlashLoan.supportsInterface";
"AirdropFlashLoan.type";
"ReentrancyGuard.supportsInterface";
"_nftWrapper.functionDelegateCall";
"AirdropFlashLoan.INftWrapper";
"AirdropFlashLoan.<Constructor>" -> "AirdropFlashLoan.INftfiHub" [ color = "#1bc6a6" ];
"AirdropFlashLoan.pullAirdrop" -> "AirdropFlashLoan.IPermittedAirdrops" [ color = "#1bc6a6" ];
"AirdropFlashLoan.pullAirdrop" -> "INftfiHub.getContract" [ color = "white" ];
"AirdropFlashLoan.pullAirdrop" -> "AirdropFlashLoan._getSelector" [ color = "#1bc6a6" ];
"AirdropFlashLoan.pullAirdrop" -> "_target.functionCall" [ color = "white" ];
"AirdropFlashLoan.pullAirdrop" -> "AirdropFlashLoan._transferNFT" [ color = "#1bc6a6" ];
"AirdropFlashLoan.pullAirdrop" -> "AirdropFlashLoan.IERC1155" [ color = "#1bc6a6" ];
"AirdropFlashLoan.pullAirdrop" -> "AirdropFlashLoan.IERC721" [ color = "#1bc6a6" ];
"AirdropFlashLoan.supportsInterface" -> "AirdropFlashLoan.type" [ color = "#1bc6a6" ];
"AirdropFlashLoan.supportsInterface" -> "ReentrancyGuard.supportsInterface" [ color = "white" ];
"AirdropFlashLoan._transferNFT" -> "_nftWrapper.functionDelegateCall" [ color = "white" ];
"AirdropFlashLoan._transferNFT" -> "AirdropFlashLoan.INftWrapper" [ color = "#1bc6a6" ];
rankdir=LR
node [shape=plaintext]
subgraph cluster_01 {
label = "Legend";
key [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
<tr><td align="right" port="i1">Internal Call</td></tr>
<tr><td align="right" port="i2">External Call</td></tr>
<tr><td align="right" port="i3">Defined Contract</td></tr>
<tr><td align="right" port="i4">Undefined Contract</td></tr>
</table>>]
key2 [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
<tr><td port="i1"> </td></tr>
<tr><td port="i2"> </td></tr>
<tr><td port="i3" bgcolor="#445773"> </td></tr>
<tr><td port="i4">
<table border="1" cellborder="0" cellspacing="0" cellpadding="7" color="#e8726d">
<tr>
<td></td>
</tr>
</table>
</td></tr>
</table>>]
key:i1:e -> key2:i1:w [color="#1bc6a6"]
key:i2:e -> key2:i2:w [color="white"]
}
}
digraph G {
graph [ ratio = "auto", page = "100", compound =true, bgcolor = "#2e3e56" ];
node [ style = "filled", fillcolor = "#edad56", color = "#edad56", penwidth =3 ];
edge [ color = "#fcfcfc", penwidth =2, fontname = "helvetica Neue Ultra Light" ];
subgraph "clusterAirdropReceiver" {
graph [ label = "AirdropReceiver", color = "#445773", fontcolor = "#f0f0f0", style = "rounded", bgcolor = "#445773" ];
"AirdropReceiver.onlyOwner" [ label = "onlyOwner", color = "#1bc6a6", shape =doubleoctagon ];
"AirdropReceiver.onlyOwnerOrBeneficiary" [ label = "onlyOwnerOrBeneficiary", color = "#1bc6a6", shape =doubleoctagon ];
"AirdropReceiver.<Constructor>" [ label = "<Constructor>", color = "#FF9797", fillcolor = "#FF9797" ];
"AirdropReceiver.getTokenId" [ label = "getTokenId" ];
"AirdropReceiver.initialize" [ label = "initialize", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"AirdropReceiver.wrap" [ label = "wrap", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"AirdropReceiver.unwrap" [ label = "unwrap", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"AirdropReceiver.pullAirdrop" [ label = "pullAirdrop", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"AirdropReceiver.supportsInterface" [ label = "supportsInterface", color = "#FF9797", fillcolor = "#FF9797" ];
"AirdropReceiver.drainERC20Airdrop" [ label = "drainERC20Airdrop", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"AirdropReceiver.drainERC721Airdrop" [ label = "drainERC721Airdrop", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"AirdropReceiver.drainERC1155Airdrop" [ label = "drainERC1155Airdrop", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"AirdropReceiver._transferNFT" [ label = "_transferNFT" ];
"AirdropReceiver._getSelector" [ label = "_getSelector" ];
"AirdropReceiver.onERC721Received" [ label = "onERC721Received", color = "#FF9797", fillcolor = "#FF9797" ];
"AirdropReceiver.onERC1155Received" [ label = "onERC1155Received", color = "#FF9797", fillcolor = "#FF9797" ];
"AirdropReceiver.onERC1155BatchReceived" [ label = "onERC1155BatchReceived", color = "#FF9797", fillcolor = "#FF9797" ];
"AirdropReceiver._receiveAndWrap" [ label = "_receiveAndWrap" ];
"AirdropReceiver.ownerOf" [ label = "ownerOf" ];
"AirdropReceiver.INftfiHub" [ label = "INftfiHub" ];
"AirdropReceiver._safeMint" [ label = "_safeMint" ];
"AirdropReceiver.IPermittedNFTs" [ label = "IPermittedNFTs" ];
"AirdropReceiver.IPermittedAirdrops" [ label = "IPermittedAirdrops" ];
"AirdropReceiver.type" [ label = "type" ];
"AirdropReceiver.IERC20" [ label = "IERC20" ];
"AirdropReceiver.IERC721" [ label = "IERC721" ];
"AirdropReceiver.IERC1155" [ label = "IERC1155" ];
"AirdropReceiver.INftWrapper" [ label = "INftWrapper" ];
}
subgraph "clusterINftfiHub" {
graph [ label = "INftfiHub", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"INftfiHub.getContract" [ label = "getContract" ];
}
subgraph "cluster_target" {
graph [ label = "_target", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"_target.functionCall" [ label = "functionCall" ];
}
subgraph "clusterReentrancyGuard" {
graph [ label = "ReentrancyGuard", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"ReentrancyGuard.supportsInterface" [ label = "supportsInterface" ];
}
subgraph "clusterIERC20" {
graph [ label = "IERC20", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"IERC20.balanceOf" [ label = "balanceOf" ];
"IERC20.safeTransfer" [ label = "safeTransfer" ];
}
subgraph "clusterIERC721" {
graph [ label = "IERC721", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"IERC721.safeTransferFrom" [ label = "safeTransferFrom" ];
}
subgraph "clusterIERC1155" {
graph [ label = "IERC1155", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"IERC1155.balanceOf" [ label = "balanceOf" ];
"IERC1155.safeTransferFrom" [ label = "safeTransferFrom" ];
}
subgraph "cluster_nftTransferWrapper" {
graph [ label = "_nftTransferWrapper", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"_nftTransferWrapper.functionDelegateCall" [ label = "functionDelegateCall" ];
}
"AirdropReceiver.onlyOwner";
"AirdropReceiver.ownerOf";
"AirdropReceiver.getTokenId";
"AirdropReceiver.onlyOwnerOrBeneficiary";
"AirdropReceiver.<Constructor>";
"AirdropReceiver.INftfiHub";
"AirdropReceiver._safeMint";
"AirdropReceiver.initialize";
"AirdropReceiver.wrap";
"AirdropReceiver.IPermittedNFTs";
"INftfiHub.getContract";
"AirdropReceiver._transferNFT";
"AirdropReceiver.unwrap";
"AirdropReceiver.pullAirdrop";
"AirdropReceiver.IPermittedAirdrops";
"AirdropReceiver._getSelector";
"_target.functionCall";
"AirdropReceiver.supportsInterface";
"AirdropReceiver.type";
"ReentrancyGuard.supportsInterface";
"AirdropReceiver.drainERC20Airdrop";
"AirdropReceiver.IERC20";
"IERC20.balanceOf";
"IERC20.safeTransfer";
"AirdropReceiver.drainERC721Airdrop";
"AirdropReceiver.IERC721";
"IERC721.safeTransferFrom";
"AirdropReceiver.drainERC1155Airdrop";
"AirdropReceiver.IERC1155";
"IERC1155.balanceOf";
"IERC1155.safeTransferFrom";
"_nftTransferWrapper.functionDelegateCall";
"AirdropReceiver.INftWrapper";
"AirdropReceiver.onERC721Received";
"AirdropReceiver._receiveAndWrap";
"AirdropReceiver.onERC1155Received";
"AirdropReceiver.onERC1155BatchReceived";
"AirdropReceiver.onlyOwner" -> "AirdropReceiver.ownerOf" [ color = "#1bc6a6" ];
"AirdropReceiver.onlyOwner" -> "AirdropReceiver.getTokenId" [ color = "#1bc6a6" ];
"AirdropReceiver.onlyOwnerOrBeneficiary" -> "AirdropReceiver.ownerOf" [ color = "#1bc6a6" ];
"AirdropReceiver.onlyOwnerOrBeneficiary" -> "AirdropReceiver.getTokenId" [ color = "#1bc6a6" ];
"AirdropReceiver.<Constructor>" -> "AirdropReceiver.INftfiHub" [ color = "#1bc6a6" ];
"AirdropReceiver.<Constructor>" -> "AirdropReceiver._safeMint" [ color = "#1bc6a6" ];
"AirdropReceiver.<Constructor>" -> "AirdropReceiver.getTokenId" [ color = "#1bc6a6" ];
"AirdropReceiver.initialize" -> "AirdropReceiver.getTokenId" [ color = "#1bc6a6" ];
"AirdropReceiver.initialize" -> "AirdropReceiver._safeMint" [ color = "#1bc6a6" ];
"AirdropReceiver.wrap" -> "AirdropReceiver.IPermittedNFTs" [ color = "#1bc6a6" ];
"AirdropReceiver.wrap" -> "INftfiHub.getContract" [ color = "white" ];
"AirdropReceiver.wrap" -> "AirdropReceiver._transferNFT" [ color = "#1bc6a6" ];
"AirdropReceiver.unwrap" -> "AirdropReceiver._transferNFT" [ color = "#1bc6a6" ];
"AirdropReceiver.pullAirdrop" -> "AirdropReceiver.IPermittedAirdrops" [ color = "#1bc6a6" ];
"AirdropReceiver.pullAirdrop" -> "INftfiHub.getContract" [ color = "white" ];
"AirdropReceiver.pullAirdrop" -> "AirdropReceiver._getSelector" [ color = "#1bc6a6" ];
"AirdropReceiver.pullAirdrop" -> "_target.functionCall" [ color = "white" ];
"AirdropReceiver.supportsInterface" -> "AirdropReceiver.type" [ color = "#1bc6a6" ];
"AirdropReceiver.supportsInterface" -> "ReentrancyGuard.supportsInterface" [ color = "white" ];
"AirdropReceiver.drainERC20Airdrop" -> "AirdropReceiver.IERC20" [ color = "#1bc6a6" ];
"AirdropReceiver.drainERC20Airdrop" -> "IERC20.balanceOf" [ color = "white" ];
"AirdropReceiver.drainERC20Airdrop" -> "IERC20.safeTransfer" [ color = "white" ];
"AirdropReceiver.drainERC721Airdrop" -> "AirdropReceiver.IERC721" [ color = "#1bc6a6" ];
"AirdropReceiver.drainERC721Airdrop" -> "IERC721.safeTransferFrom" [ color = "white" ];
"AirdropReceiver.drainERC1155Airdrop" -> "AirdropReceiver.IERC1155" [ color = "#1bc6a6" ];
"AirdropReceiver.drainERC1155Airdrop" -> "IERC1155.balanceOf" [ color = "white" ];
"AirdropReceiver.drainERC1155Airdrop" -> "IERC1155.safeTransferFrom" [ color = "white" ];
"AirdropReceiver._transferNFT" -> "_nftTransferWrapper.functionDelegateCall" [ color = "white" ];
"AirdropReceiver._transferNFT" -> "AirdropReceiver.INftWrapper" [ color = "#1bc6a6" ];
"AirdropReceiver.onERC721Received" -> "AirdropReceiver.ownerOf" [ color = "#1bc6a6" ];
"AirdropReceiver.onERC721Received" -> "AirdropReceiver.getTokenId" [ color = "#1bc6a6" ];
"AirdropReceiver.onERC721Received" -> "AirdropReceiver._receiveAndWrap" [ color = "#1bc6a6" ];
"AirdropReceiver.onERC1155Received" -> "AirdropReceiver.ownerOf" [ color = "#1bc6a6" ];
"AirdropReceiver.onERC1155Received" -> "AirdropReceiver.getTokenId" [ color = "#1bc6a6" ];
"AirdropReceiver.onERC1155Received" -> "AirdropReceiver._receiveAndWrap" [ color = "#1bc6a6" ];
"AirdropReceiver.onERC1155BatchReceived" -> "AirdropReceiver.ownerOf" [ color = "#1bc6a6" ];
"AirdropReceiver.onERC1155BatchReceived" -> "AirdropReceiver.getTokenId" [ color = "#1bc6a6" ];
"AirdropReceiver.onERC1155BatchReceived" -> "AirdropReceiver._receiveAndWrap" [ color = "#1bc6a6" ];
"AirdropReceiver._receiveAndWrap" -> "AirdropReceiver.IPermittedNFTs" [ color = "#1bc6a6" ];
"AirdropReceiver._receiveAndWrap" -> "INftfiHub.getContract" [ color = "white" ];
rankdir=LR
node [shape=plaintext]
subgraph cluster_01 {
label = "Legend";
key [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
<tr><td align="right" port="i1">Internal Call</td></tr>
<tr><td align="right" port="i2">External Call</td></tr>
<tr><td align="right" port="i3">Defined Contract</td></tr>
<tr><td align="right" port="i4">Undefined Contract</td></tr>
</table>>]
key2 [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
<tr><td port="i1"> </td></tr>
<tr><td port="i2"> </td></tr>
<tr><td port="i3" bgcolor="#445773"> </td></tr>
<tr><td port="i4">
<table border="1" cellborder="0" cellspacing="0" cellpadding="7" color="#e8726d">
<tr>
<td></td>
</tr>
</table>
</td></tr>
</table>>]
key:i1:e -> key2:i1:w [color="#1bc6a6"]
key:i2:e -> key2:i2:w [color="white"]
}
}
digraph G {
graph [ ratio = "auto", page = "100", compound =true, bgcolor = "#2e3e56" ];
node [ style = "filled", fillcolor = "#edad56", color = "#edad56", penwidth =3 ];
edge [ color = "#fcfcfc", penwidth =2, fontname = "helvetica Neue Ultra Light" ];
subgraph "clusterDirectLoanBaseMinimal" {
graph [ label = "DirectLoanBaseMinimal", color = "#445773", fontcolor = "#f0f0f0", style = "rounded", bgcolor = "#445773" ];
"DirectLoanBaseMinimal.<Constructor>" [ label = "<Constructor>", color = "#FF9797", fillcolor = "#FF9797" ];
"DirectLoanBaseMinimal.updateMaximumLoanDuration" [ label = "updateMaximumLoanDuration", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanBaseMinimal.updateAdminFee" [ label = "updateAdminFee", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanBaseMinimal.drainERC20Airdrop" [ label = "drainERC20Airdrop", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanBaseMinimal.setERC20Permit" [ label = "setERC20Permit", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanBaseMinimal.setERC20Permits" [ label = "setERC20Permits", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanBaseMinimal.drainERC721Airdrop" [ label = "drainERC721Airdrop", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanBaseMinimal.drainERC1155Airdrop" [ label = "drainERC1155Airdrop", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanBaseMinimal.mintObligationReceipt" [ label = "mintObligationReceipt", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanBaseMinimal.renegotiateLoan" [ label = "renegotiateLoan", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanBaseMinimal.payBackLoan" [ label = "payBackLoan", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanBaseMinimal.liquidateOverdueLoan" [ label = "liquidateOverdueLoan", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanBaseMinimal.pullAirdrop" [ label = "pullAirdrop", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanBaseMinimal.wrapCollateral" [ label = "wrapCollateral", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanBaseMinimal.cancelLoanCommitmentBeforeLoanHasBegun" [ label = "cancelLoanCommitmentBeforeLoanHasBegun", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanBaseMinimal.getPayoffAmount" [ label = "getPayoffAmount", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanBaseMinimal.getWhetherNonceHasBeenUsedForUser" [ label = "getWhetherNonceHasBeenUsedForUser", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanBaseMinimal.getERC20Permit" [ label = "getERC20Permit" ];
"DirectLoanBaseMinimal._renegotiateLoan" [ label = "_renegotiateLoan" ];
"DirectLoanBaseMinimal._createLoan" [ label = "_createLoan", color = "#f2c383", fillcolor = "#f2c383" ];
"DirectLoanBaseMinimal._createLoanNoNftTransfer" [ label = "_createLoanNoNftTransfer" ];
"DirectLoanBaseMinimal._transferNFT" [ label = "_transferNFT" ];
"DirectLoanBaseMinimal._payBackLoan" [ label = "_payBackLoan" ];
"DirectLoanBaseMinimal._resolveLoan" [ label = "_resolveLoan" ];
"DirectLoanBaseMinimal._resolveLoanNoNftTransfer" [ label = "_resolveLoanNoNftTransfer" ];
"DirectLoanBaseMinimal._setERC20Permit" [ label = "_setERC20Permit" ];
"DirectLoanBaseMinimal._loanSanityChecks" [ label = "_loanSanityChecks", color = "#f2c383", fillcolor = "#f2c383" ];
"DirectLoanBaseMinimal._getPartiesAndData" [ label = "_getPartiesAndData" ];
"DirectLoanBaseMinimal._setupLoanExtras" [ label = "_setupLoanExtras", color = "#f2c383", fillcolor = "#f2c383" ];
"DirectLoanBaseMinimal._payoffAndFee" [ label = "_payoffAndFee" ];
"DirectLoanBaseMinimal._getWrapper" [ label = "_getWrapper", color = "#f2c383", fillcolor = "#f2c383" ];
"DirectLoanBaseMinimal.INftfiHub" [ label = "INftfiHub" ];
"DirectLoanBaseMinimal.type" [ label = "type" ];
"DirectLoanBaseMinimal.IERC20" [ label = "IERC20" ];
"DirectLoanBaseMinimal.IERC721" [ label = "IERC721" ];
"DirectLoanBaseMinimal.IERC1155" [ label = "IERC1155" ];
"DirectLoanBaseMinimal.IDirectLoanCoordinator" [ label = "IDirectLoanCoordinator" ];
"DirectLoanBaseMinimal.Signature" [ label = "Signature" ];
"DirectLoanBaseMinimal.owner" [ label = "owner" ];
"DirectLoanBaseMinimal.INftWrapper" [ label = "INftWrapper" ];
"DirectLoanBaseMinimal.LoanExtras" [ label = "LoanExtras" ];
"DirectLoanBaseMinimal.IPermittedNFTs" [ label = "IPermittedNFTs" ];
}
subgraph "clusterIERC20" {
graph [ label = "IERC20", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"IERC20.balanceOf" [ label = "balanceOf" ];
"IERC20.safeTransfer" [ label = "safeTransfer" ];
}
subgraph "clusterIERC721" {
graph [ label = "IERC721", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"IERC721.ownerOf" [ label = "ownerOf" ];
"IERC721.safeTransferFrom" [ label = "safeTransferFrom" ];
}
subgraph "clusterIERC1155" {
graph [ label = "IERC1155", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"IERC1155.balanceOf" [ label = "balanceOf" ];
"IERC1155.safeTransferFrom" [ label = "safeTransferFrom" ];
}
subgraph "clusterINftfiHub" {
graph [ label = "INftfiHub", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"INftfiHub.getContract" [ label = "getContract" ];
}
subgraph "clusterIDirectLoanCoordinator" {
graph [ label = "IDirectLoanCoordinator", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"IDirectLoanCoordinator.mintObligationReceipt" [ label = "mintObligationReceipt" ];
"IDirectLoanCoordinator.registerLoan" [ label = "registerLoan" ];
"IDirectLoanCoordinator.resolveLoan" [ label = "resolveLoan" ];
"IDirectLoanCoordinator.getLoanData" [ label = "getLoanData" ];
"IDirectLoanCoordinator.obligationReceiptToken" [ label = "obligationReceiptToken" ];
"IDirectLoanCoordinator.promissoryNoteToken" [ label = "promissoryNoteToken" ];
}
subgraph "clusterLoanChecksAndCalculations" {
graph [ label = "LoanChecksAndCalculations", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"LoanChecksAndCalculations.payBackChecks" [ label = "payBackChecks" ];
"LoanChecksAndCalculations.checkLoanIdValidity" [ label = "checkLoanIdValidity" ];
"LoanChecksAndCalculations.renegotiationChecks" [ label = "renegotiationChecks" ];
"LoanChecksAndCalculations.computeAdminFee" [ label = "computeAdminFee" ];
"LoanChecksAndCalculations.computeReferralFee" [ label = "computeReferralFee" ];
"LoanChecksAndCalculations.computeRevenueShare" [ label = "computeRevenueShare" ];
"LoanChecksAndCalculations.getRevenueSharePercent" [ label = "getRevenueSharePercent" ];
}
subgraph "clusterLoanAirdropUtils" {
graph [ label = "LoanAirdropUtils", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"LoanAirdropUtils.pullAirdrop" [ label = "pullAirdrop" ];
"LoanAirdropUtils.wrapCollateral" [ label = "wrapCollateral" ];
}
subgraph "clusterNFTfiSigningUtils" {
graph [ label = "NFTfiSigningUtils", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"NFTfiSigningUtils.isValidLenderRenegotiationSignature" [ label = "isValidLenderRenegotiationSignature" ];
}
subgraph "clusterAddress" {
graph [ label = "Address", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"Address.functionDelegateCall" [ label = "functionDelegateCall" ];
}
"DirectLoanBaseMinimal.<Constructor>";
"DirectLoanBaseMinimal.INftfiHub";
"DirectLoanBaseMinimal._setERC20Permit";
"DirectLoanBaseMinimal.updateMaximumLoanDuration";
"DirectLoanBaseMinimal.type";
"DirectLoanBaseMinimal.drainERC20Airdrop";
"DirectLoanBaseMinimal.IERC20";
"IERC20.balanceOf";
"IERC20.safeTransfer";
"DirectLoanBaseMinimal.setERC20Permit";
"DirectLoanBaseMinimal.setERC20Permits";
"DirectLoanBaseMinimal.drainERC721Airdrop";
"DirectLoanBaseMinimal.IERC721";
"IERC721.ownerOf";
"IERC721.safeTransferFrom";
"DirectLoanBaseMinimal.drainERC1155Airdrop";
"DirectLoanBaseMinimal.IERC1155";
"IERC1155.balanceOf";
"IERC1155.safeTransferFrom";
"DirectLoanBaseMinimal.mintObligationReceipt";
"DirectLoanBaseMinimal.IDirectLoanCoordinator";
"INftfiHub.getContract";
"IDirectLoanCoordinator.mintObligationReceipt";
"DirectLoanBaseMinimal.renegotiateLoan";
"DirectLoanBaseMinimal._renegotiateLoan";
"DirectLoanBaseMinimal.payBackLoan";
"LoanChecksAndCalculations.payBackChecks";
"DirectLoanBaseMinimal._getPartiesAndData";
"DirectLoanBaseMinimal._payBackLoan";
"DirectLoanBaseMinimal._resolveLoan";
"DirectLoanBaseMinimal.liquidateOverdueLoan";
"LoanChecksAndCalculations.checkLoanIdValidity";
"DirectLoanBaseMinimal.pullAirdrop";
"LoanAirdropUtils.pullAirdrop";
"DirectLoanBaseMinimal.wrapCollateral";
"LoanAirdropUtils.wrapCollateral";
"LoanChecksAndCalculations.renegotiationChecks";
"NFTfiSigningUtils.isValidLenderRenegotiationSignature";
"DirectLoanBaseMinimal.Signature";
"LoanChecksAndCalculations.computeAdminFee";
"DirectLoanBaseMinimal.owner";
"DirectLoanBaseMinimal._createLoan";
"DirectLoanBaseMinimal._transferNFT";
"DirectLoanBaseMinimal._createLoanNoNftTransfer";
"LoanChecksAndCalculations.computeReferralFee";
"IDirectLoanCoordinator.registerLoan";
"Address.functionDelegateCall";
"DirectLoanBaseMinimal.INftWrapper";
"DirectLoanBaseMinimal._payoffAndFee";
"LoanChecksAndCalculations.computeRevenueShare";
"DirectLoanBaseMinimal._resolveLoanNoNftTransfer";
"IDirectLoanCoordinator.resolveLoan";
"DirectLoanBaseMinimal._loanSanityChecks";
"DirectLoanBaseMinimal.getERC20Permit";
"IDirectLoanCoordinator.getLoanData";
"IDirectLoanCoordinator.obligationReceiptToken";
"IDirectLoanCoordinator.promissoryNoteToken";
"DirectLoanBaseMinimal._setupLoanExtras";
"DirectLoanBaseMinimal.LoanExtras";
"LoanChecksAndCalculations.getRevenueSharePercent";
"DirectLoanBaseMinimal._getWrapper";
"DirectLoanBaseMinimal.IPermittedNFTs";
"DirectLoanBaseMinimal.<Constructor>" -> "DirectLoanBaseMinimal.INftfiHub" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal.<Constructor>" -> "DirectLoanBaseMinimal._setERC20Permit" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal.updateMaximumLoanDuration" -> "DirectLoanBaseMinimal.type" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal.drainERC20Airdrop" -> "DirectLoanBaseMinimal.IERC20" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal.drainERC20Airdrop" -> "IERC20.balanceOf" [ color = "white" ];
"DirectLoanBaseMinimal.drainERC20Airdrop" -> "IERC20.safeTransfer" [ color = "white" ];
"DirectLoanBaseMinimal.setERC20Permit" -> "DirectLoanBaseMinimal._setERC20Permit" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal.setERC20Permits" -> "DirectLoanBaseMinimal._setERC20Permit" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal.drainERC721Airdrop" -> "DirectLoanBaseMinimal.IERC721" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal.drainERC721Airdrop" -> "IERC721.ownerOf" [ color = "white" ];
"DirectLoanBaseMinimal.drainERC721Airdrop" -> "IERC721.safeTransferFrom" [ color = "white" ];
"DirectLoanBaseMinimal.drainERC1155Airdrop" -> "DirectLoanBaseMinimal.IERC1155" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal.drainERC1155Airdrop" -> "IERC1155.balanceOf" [ color = "white" ];
"DirectLoanBaseMinimal.drainERC1155Airdrop" -> "IERC1155.safeTransferFrom" [ color = "white" ];
"DirectLoanBaseMinimal.mintObligationReceipt" -> "DirectLoanBaseMinimal.IDirectLoanCoordinator" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal.mintObligationReceipt" -> "INftfiHub.getContract" [ color = "white" ];
"DirectLoanBaseMinimal.mintObligationReceipt" -> "IDirectLoanCoordinator.mintObligationReceipt" [ color = "white" ];
"DirectLoanBaseMinimal.renegotiateLoan" -> "DirectLoanBaseMinimal._renegotiateLoan" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal.payBackLoan" -> "LoanChecksAndCalculations.payBackChecks" [ color = "white" ];
"DirectLoanBaseMinimal.payBackLoan" -> "DirectLoanBaseMinimal._getPartiesAndData" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal.payBackLoan" -> "DirectLoanBaseMinimal._payBackLoan" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal.payBackLoan" -> "DirectLoanBaseMinimal._resolveLoan" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal.liquidateOverdueLoan" -> "LoanChecksAndCalculations.checkLoanIdValidity" [ color = "white" ];
"DirectLoanBaseMinimal.liquidateOverdueLoan" -> "DirectLoanBaseMinimal._getPartiesAndData" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal.liquidateOverdueLoan" -> "DirectLoanBaseMinimal._resolveLoan" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal.pullAirdrop" -> "LoanChecksAndCalculations.checkLoanIdValidity" [ color = "white" ];
"DirectLoanBaseMinimal.pullAirdrop" -> "LoanAirdropUtils.pullAirdrop" [ color = "white" ];
"DirectLoanBaseMinimal.wrapCollateral" -> "LoanChecksAndCalculations.checkLoanIdValidity" [ color = "white" ];
"DirectLoanBaseMinimal.wrapCollateral" -> "LoanAirdropUtils.wrapCollateral" [ color = "white" ];
"DirectLoanBaseMinimal._renegotiateLoan" -> "LoanChecksAndCalculations.renegotiationChecks" [ color = "white" ];
"DirectLoanBaseMinimal._renegotiateLoan" -> "NFTfiSigningUtils.isValidLenderRenegotiationSignature" [ color = "white" ];
"DirectLoanBaseMinimal._renegotiateLoan" -> "DirectLoanBaseMinimal.Signature" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal._renegotiateLoan" -> "LoanChecksAndCalculations.computeAdminFee" [ color = "white" ];
"DirectLoanBaseMinimal._renegotiateLoan" -> "DirectLoanBaseMinimal.IERC20" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal._renegotiateLoan" -> "DirectLoanBaseMinimal.IERC20" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal._renegotiateLoan" -> "DirectLoanBaseMinimal.owner" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal._createLoan" -> "DirectLoanBaseMinimal._transferNFT" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal._createLoan" -> "DirectLoanBaseMinimal._createLoanNoNftTransfer" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal._createLoanNoNftTransfer" -> "LoanChecksAndCalculations.computeReferralFee" [ color = "white" ];
"DirectLoanBaseMinimal._createLoanNoNftTransfer" -> "DirectLoanBaseMinimal.IERC20" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal._createLoanNoNftTransfer" -> "DirectLoanBaseMinimal.IERC20" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal._createLoanNoNftTransfer" -> "DirectLoanBaseMinimal.IDirectLoanCoordinator" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal._createLoanNoNftTransfer" -> "INftfiHub.getContract" [ color = "white" ];
"DirectLoanBaseMinimal._createLoanNoNftTransfer" -> "IDirectLoanCoordinator.registerLoan" [ color = "white" ];
"DirectLoanBaseMinimal._transferNFT" -> "Address.functionDelegateCall" [ color = "white" ];
"DirectLoanBaseMinimal._transferNFT" -> "DirectLoanBaseMinimal.INftWrapper" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal._payBackLoan" -> "DirectLoanBaseMinimal._payoffAndFee" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal._payBackLoan" -> "DirectLoanBaseMinimal.IERC20" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal._payBackLoan" -> "LoanChecksAndCalculations.computeRevenueShare" [ color = "white" ];
"DirectLoanBaseMinimal._payBackLoan" -> "DirectLoanBaseMinimal.IERC20" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal._payBackLoan" -> "DirectLoanBaseMinimal.IERC20" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal._payBackLoan" -> "DirectLoanBaseMinimal.owner" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal._resolveLoan" -> "DirectLoanBaseMinimal._resolveLoanNoNftTransfer" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal._resolveLoan" -> "DirectLoanBaseMinimal._transferNFT" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal._resolveLoanNoNftTransfer" -> "IDirectLoanCoordinator.resolveLoan" [ color = "white" ];
"DirectLoanBaseMinimal._loanSanityChecks" -> "DirectLoanBaseMinimal.getERC20Permit" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal._getPartiesAndData" -> "DirectLoanBaseMinimal.IDirectLoanCoordinator" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal._getPartiesAndData" -> "INftfiHub.getContract" [ color = "white" ];
"DirectLoanBaseMinimal._getPartiesAndData" -> "IDirectLoanCoordinator.getLoanData" [ color = "white" ];
"DirectLoanBaseMinimal._getPartiesAndData" -> "DirectLoanBaseMinimal.IERC721" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal._getPartiesAndData" -> "IDirectLoanCoordinator.obligationReceiptToken" [ color = "white" ];
"DirectLoanBaseMinimal._getPartiesAndData" -> "DirectLoanBaseMinimal.IERC721" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal._getPartiesAndData" -> "IDirectLoanCoordinator.promissoryNoteToken" [ color = "white" ];
"DirectLoanBaseMinimal._setupLoanExtras" -> "DirectLoanBaseMinimal.LoanExtras" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal._setupLoanExtras" -> "LoanChecksAndCalculations.getRevenueSharePercent" [ color = "white" ];
"DirectLoanBaseMinimal._getWrapper" -> "DirectLoanBaseMinimal.IPermittedNFTs" [ color = "#1bc6a6" ];
"DirectLoanBaseMinimal._getWrapper" -> "INftfiHub.getContract" [ color = "white" ];
rankdir=LR
node [shape=plaintext]
subgraph cluster_01 {
label = "Legend";
key [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
<tr><td align="right" port="i1">Internal Call</td></tr>
<tr><td align="right" port="i2">External Call</td></tr>
<tr><td align="right" port="i3">Defined Contract</td></tr>
<tr><td align="right" port="i4">Undefined Contract</td></tr>
</table>>]
key2 [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
<tr><td port="i1"> </td></tr>
<tr><td port="i2"> </td></tr>
<tr><td port="i3" bgcolor="#445773"> </td></tr>
<tr><td port="i4">
<table border="1" cellborder="0" cellspacing="0" cellpadding="7" color="#e8726d">
<tr>
<td></td>
</tr>
</table>
</td></tr>
</table>>]
key:i1:e -> key2:i1:w [color="#1bc6a6"]
key:i2:e -> key2:i2:w [color="white"]
}
}
digraph G {
graph [ ratio = "auto", page = "100", compound =true, bgcolor = "#2e3e56" ];
node [ style = "filled", fillcolor = "#edad56", color = "#edad56", penwidth =3 ];
edge [ color = "#fcfcfc", penwidth =2, fontname = "helvetica Neue Ultra Light" ];
subgraph "clusterDirectLoanFixedOffer" {
graph [ label = "DirectLoanFixedOffer", color = "#445773", fontcolor = "#f0f0f0", style = "rounded", bgcolor = "#445773" ];
"DirectLoanFixedOffer.<Constructor>" [ label = "<Constructor>", color = "#FF9797", fillcolor = "#FF9797" ];
"DirectLoanFixedOffer.acceptOffer" [ label = "acceptOffer", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanFixedOffer.getPayoffAmount" [ label = "getPayoffAmount", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanFixedOffer._acceptOffer" [ label = "_acceptOffer" ];
"DirectLoanFixedOffer._setupLoanTerms" [ label = "_setupLoanTerms" ];
"DirectLoanFixedOffer._payoffAndFee" [ label = "_payoffAndFee", color = "#f2c383", fillcolor = "#f2c383" ];
"DirectLoanFixedOffer._loanSanityChecksOffer" [ label = "_loanSanityChecksOffer" ];
"DirectLoanFixedOffer._getWrapper" [ label = "_getWrapper" ];
"DirectLoanFixedOffer._loanSanityChecks" [ label = "_loanSanityChecks" ];
"DirectLoanFixedOffer._setupLoanExtras" [ label = "_setupLoanExtras" ];
"DirectLoanFixedOffer._createLoan" [ label = "_createLoan" ];
"DirectLoanFixedOffer.LoanStarted" [ label = "LoanStarted" ];
"DirectLoanFixedOffer.LoanTerms" [ label = "LoanTerms" ];
}
subgraph "clusterContractKeys" {
graph [ label = "ContractKeys", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"ContractKeys.getIdFromStringKey" [ label = "getIdFromStringKey" ];
}
subgraph "clusterhub" {
graph [ label = "hub", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"hub.getContract" [ label = "getContract" ];
}
subgraph "clusterLoanChecksAndCalculations" {
graph [ label = "LoanChecksAndCalculations", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"LoanChecksAndCalculations.computeAdminFee" [ label = "computeAdminFee" ];
}
"DirectLoanFixedOffer.<Constructor>";
"ContractKeys.getIdFromStringKey";
"DirectLoanFixedOffer.acceptOffer";
"DirectLoanFixedOffer._getWrapper";
"DirectLoanFixedOffer._loanSanityChecks";
"DirectLoanFixedOffer._loanSanityChecksOffer";
"DirectLoanFixedOffer._acceptOffer";
"DirectLoanFixedOffer._setupLoanTerms";
"DirectLoanFixedOffer._setupLoanExtras";
"hub.getContract";
"DirectLoanFixedOffer._createLoan";
"DirectLoanFixedOffer.LoanStarted";
"DirectLoanFixedOffer.LoanTerms";
"DirectLoanFixedOffer._payoffAndFee";
"LoanChecksAndCalculations.computeAdminFee";
"DirectLoanFixedOffer.<Constructor>" -> "ContractKeys.getIdFromStringKey" [ color = "white" ];
"DirectLoanFixedOffer.acceptOffer" -> "DirectLoanFixedOffer._getWrapper" [ color = "#1bc6a6" ];
"DirectLoanFixedOffer.acceptOffer" -> "DirectLoanFixedOffer._loanSanityChecks" [ color = "#1bc6a6" ];
"DirectLoanFixedOffer.acceptOffer" -> "DirectLoanFixedOffer._loanSanityChecksOffer" [ color = "#1bc6a6" ];
"DirectLoanFixedOffer.acceptOffer" -> "DirectLoanFixedOffer._acceptOffer" [ color = "#1bc6a6" ];
"DirectLoanFixedOffer.acceptOffer" -> "DirectLoanFixedOffer._setupLoanTerms" [ color = "#1bc6a6" ];
"DirectLoanFixedOffer.acceptOffer" -> "DirectLoanFixedOffer._setupLoanExtras" [ color = "#1bc6a6" ];
"DirectLoanFixedOffer._acceptOffer" -> "hub.getContract" [ color = "white" ];
"DirectLoanFixedOffer._acceptOffer" -> "DirectLoanFixedOffer._createLoan" [ color = "#1bc6a6" ];
"DirectLoanFixedOffer._acceptOffer" -> "DirectLoanFixedOffer.LoanStarted" [ color = "#1bc6a6" ];
"DirectLoanFixedOffer._setupLoanTerms" -> "DirectLoanFixedOffer.LoanTerms" [ color = "#1bc6a6" ];
"DirectLoanFixedOffer._payoffAndFee" -> "LoanChecksAndCalculations.computeAdminFee" [ color = "white" ];
rankdir=LR
node [shape=plaintext]
subgraph cluster_01 {
label = "Legend";
key [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
<tr><td align="right" port="i1">Internal Call</td></tr>
<tr><td align="right" port="i2">External Call</td></tr>
<tr><td align="right" port="i3">Defined Contract</td></tr>
<tr><td align="right" port="i4">Undefined Contract</td></tr>
</table>>]
key2 [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
<tr><td port="i1"> </td></tr>
<tr><td port="i2"> </td></tr>
<tr><td port="i3" bgcolor="#445773"> </td></tr>
<tr><td port="i4">
<table border="1" cellborder="0" cellspacing="0" cellpadding="7" color="#e8726d">
<tr>
<td></td>
</tr>
</table>
</td></tr>
</table>>]
key:i1:e -> key2:i1:w [color="#1bc6a6"]
key:i2:e -> key2:i2:w [color="white"]
}
}
digraph G {
graph [ ratio = "auto", page = "100", compound =true, bgcolor = "#2e3e56" ];
node [ style = "filled", fillcolor = "#edad56", color = "#edad56", penwidth =3 ];
edge [ color = "#fcfcfc", penwidth =2, fontname = "helvetica Neue Ultra Light" ];
subgraph "clusterDirectLoanCoordinator" {
graph [ label = "DirectLoanCoordinator", color = "#445773", fontcolor = "#f0f0f0", style = "rounded", bgcolor = "#445773" ];
"DirectLoanCoordinator.onlyInitialized" [ label = "onlyInitialized", color = "#1bc6a6", shape =doubleoctagon ];
"DirectLoanCoordinator.<Constructor>" [ label = "<Constructor>", color = "#FF9797", fillcolor = "#FF9797" ];
"DirectLoanCoordinator.initialize" [ label = "initialize", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanCoordinator.registerLoan" [ label = "registerLoan", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanCoordinator.mintObligationReceipt" [ label = "mintObligationReceipt", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanCoordinator.resolveLoan" [ label = "resolveLoan", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanCoordinator.getLoanData" [ label = "getLoanData", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanCoordinator.isValidLoanId" [ label = "isValidLoanId", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanCoordinator.registerLoanType" [ label = "registerLoanType", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanCoordinator.registerLoanTypes" [ label = "registerLoanTypes", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"DirectLoanCoordinator.getContractFromType" [ label = "getContractFromType" ];
"DirectLoanCoordinator.getTypeFromContract" [ label = "getTypeFromContract" ];
"DirectLoanCoordinator._registerLoanType" [ label = "_registerLoanType" ];
"DirectLoanCoordinator._registerLoanTypes" [ label = "_registerLoanTypes" ];
"DirectLoanCoordinator.INftfiHub" [ label = "INftfiHub" ];
"DirectLoanCoordinator.Loan" [ label = "Loan" ];
"DirectLoanCoordinator.SmartNft" [ label = "SmartNft" ];
}
subgraph "clusterContractKeys" {
graph [ label = "ContractKeys", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"ContractKeys.getIdFromStringKey" [ label = "getIdFromStringKey" ];
}
"DirectLoanCoordinator.<Constructor>";
"DirectLoanCoordinator.INftfiHub";
"DirectLoanCoordinator._registerLoanTypes";
"DirectLoanCoordinator.registerLoan";
"DirectLoanCoordinator.getContractFromType";
"DirectLoanCoordinator.Loan";
"DirectLoanCoordinator.SmartNft";
"DirectLoanCoordinator.mintObligationReceipt";
"DirectLoanCoordinator.getTypeFromContract";
"DirectLoanCoordinator.resolveLoan";
"DirectLoanCoordinator.registerLoanType";
"DirectLoanCoordinator._registerLoanType";
"DirectLoanCoordinator.registerLoanTypes";
"ContractKeys.getIdFromStringKey";
"DirectLoanCoordinator.<Constructor>" -> "DirectLoanCoordinator.INftfiHub" [ color = "#1bc6a6" ];
"DirectLoanCoordinator.<Constructor>" -> "DirectLoanCoordinator._registerLoanTypes" [ color = "#1bc6a6" ];
"DirectLoanCoordinator.registerLoan" -> "DirectLoanCoordinator.getContractFromType" [ color = "#1bc6a6" ];
"DirectLoanCoordinator.registerLoan" -> "DirectLoanCoordinator.Loan" [ color = "#1bc6a6" ];
"DirectLoanCoordinator.registerLoan" -> "DirectLoanCoordinator.SmartNft" [ color = "#1bc6a6" ];
"DirectLoanCoordinator.mintObligationReceipt" -> "DirectLoanCoordinator.getTypeFromContract" [ color = "#1bc6a6" ];
"DirectLoanCoordinator.mintObligationReceipt" -> "DirectLoanCoordinator.SmartNft" [ color = "#1bc6a6" ];
"DirectLoanCoordinator.mintObligationReceipt" -> "DirectLoanCoordinator.SmartNft" [ color = "#1bc6a6" ];
"DirectLoanCoordinator.mintObligationReceipt" -> "DirectLoanCoordinator.SmartNft" [ color = "#1bc6a6" ];
"DirectLoanCoordinator.resolveLoan" -> "DirectLoanCoordinator.SmartNft" [ color = "#1bc6a6" ];
"DirectLoanCoordinator.resolveLoan" -> "DirectLoanCoordinator.SmartNft" [ color = "#1bc6a6" ];
"DirectLoanCoordinator.resolveLoan" -> "DirectLoanCoordinator.SmartNft" [ color = "#1bc6a6" ];
"DirectLoanCoordinator.registerLoanType" -> "DirectLoanCoordinator._registerLoanType" [ color = "#1bc6a6" ];
"DirectLoanCoordinator.registerLoanTypes" -> "DirectLoanCoordinator._registerLoanTypes" [ color = "#1bc6a6" ];
"DirectLoanCoordinator._registerLoanType" -> "ContractKeys.getIdFromStringKey" [ color = "white" ];
"DirectLoanCoordinator._registerLoanTypes" -> "DirectLoanCoordinator._registerLoanType" [ color = "#1bc6a6" ];
rankdir=LR
node [shape=plaintext]
subgraph cluster_01 {
label = "Legend";
key [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
<tr><td align="right" port="i1">Internal Call</td></tr>
<tr><td align="right" port="i2">External Call</td></tr>
<tr><td align="right" port="i3">Defined Contract</td></tr>
<tr><td align="right" port="i4">Undefined Contract</td></tr>
</table>>]
key2 [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
<tr><td port="i1"> </td></tr>
<tr><td port="i2"> </td></tr>
<tr><td port="i3" bgcolor="#445773"> </td></tr>
<tr><td port="i4">
<table border="1" cellborder="0" cellspacing="0" cellpadding="7" color="#e8726d">
<tr>
<td></td>
</tr>
</table>
</td></tr>
</table>>]
key:i1:e -> key2:i1:w [color="#1bc6a6"]
key:i2:e -> key2:i2:w [color="white"]
}
}
digraph G {
graph [ ratio = "auto", page = "100", compound =true, bgcolor = "#2e3e56" ];
node [ style = "filled", fillcolor = "#edad56", color = "#edad56", penwidth =3 ];
edge [ color = "#fcfcfc", penwidth =2, fontname = "helvetica Neue Ultra Light" ];
subgraph "clusterSmartNft" {
graph [ label = "SmartNft", color = "#445773", fontcolor = "#f0f0f0", style = "rounded", bgcolor = "#445773" ];
"SmartNft.<Constructor>" [ label = "<Constructor>", color = "#FF9797", fillcolor = "#FF9797" ];
"SmartNft.setLoanCoordinator" [ label = "setLoanCoordinator", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"SmartNft.mint" [ label = "mint", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"SmartNft.burn" [ label = "burn", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"SmartNft.setBaseURI" [ label = "setBaseURI", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"SmartNft.exists" [ label = "exists", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"SmartNft.supportsInterface" [ label = "supportsInterface", color = "#FF9797", fillcolor = "#FF9797" ];
"SmartNft._setBaseURI" [ label = "_setBaseURI" ];
"SmartNft._baseURI" [ label = "_baseURI", color = "#f2c383", fillcolor = "#f2c383" ];
"SmartNft._getChainID" [ label = "_getChainID" ];
"SmartNft._setupRole" [ label = "_setupRole" ];
"SmartNft.INftfiHub" [ label = "INftfiHub" ];
"SmartNft.grantRole" [ label = "grantRole" ];
"SmartNft._safeMint" [ label = "_safeMint" ];
"SmartNft._burn" [ label = "_burn" ];
"SmartNft._exists" [ label = "_exists" ];
}
subgraph "clusterAccessControl" {
graph [ label = "AccessControl", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"AccessControl.supportsInterface" [ label = "supportsInterface" ];
}
"SmartNft.<Constructor>";
"SmartNft._setupRole";
"SmartNft._setBaseURI";
"SmartNft.INftfiHub";
"SmartNft.setLoanCoordinator";
"SmartNft.grantRole";
"SmartNft.mint";
"SmartNft._safeMint";
"SmartNft.burn";
"SmartNft._burn";
"SmartNft.setBaseURI";
"SmartNft.exists";
"SmartNft._exists";
"SmartNft.supportsInterface";
"AccessControl.supportsInterface";
"SmartNft._getChainID";
"SmartNft.<Constructor>" -> "SmartNft._setupRole" [ color = "#1bc6a6" ];
"SmartNft.<Constructor>" -> "SmartNft._setupRole" [ color = "#1bc6a6" ];
"SmartNft.<Constructor>" -> "SmartNft._setupRole" [ color = "#1bc6a6" ];
"SmartNft.<Constructor>" -> "SmartNft._setBaseURI" [ color = "#1bc6a6" ];
"SmartNft.<Constructor>" -> "SmartNft.INftfiHub" [ color = "#1bc6a6" ];
"SmartNft.setLoanCoordinator" -> "SmartNft.grantRole" [ color = "#1bc6a6" ];
"SmartNft.mint" -> "SmartNft._safeMint" [ color = "#1bc6a6" ];
"SmartNft.burn" -> "SmartNft._burn" [ color = "#1bc6a6" ];
"SmartNft.setBaseURI" -> "SmartNft._setBaseURI" [ color = "#1bc6a6" ];
"SmartNft.exists" -> "SmartNft._exists" [ color = "#1bc6a6" ];
"SmartNft.supportsInterface" -> "AccessControl.supportsInterface" [ color = "white" ];
"SmartNft._setBaseURI" -> "SmartNft._getChainID" [ color = "#1bc6a6" ];
rankdir=LR
node [shape=plaintext]
subgraph cluster_01 {
label = "Legend";
key [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
<tr><td align="right" port="i1">Internal Call</td></tr>
<tr><td align="right" port="i2">External Call</td></tr>
<tr><td align="right" port="i3">Defined Contract</td></tr>
<tr><td align="right" port="i4">Undefined Contract</td></tr>
</table>>]
key2 [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
<tr><td port="i1"> </td></tr>
<tr><td port="i2"> </td></tr>
<tr><td port="i3" bgcolor="#445773"> </td></tr>
<tr><td port="i4">
<table border="1" cellborder="0" cellspacing="0" cellpadding="7" color="#e8726d">
<tr>
<td></td>
</tr>
</table>
</td></tr>
</table>>]
key:i1:e -> key2:i1:w [color="#1bc6a6"]
key:i2:e -> key2:i2:w [color="white"]
}
}
digraph G {
graph [ ratio = "auto", page = "100", compound =true, bgcolor = "#2e3e56" ];
node [ style = "filled", fillcolor = "#edad56", color = "#edad56", penwidth =3 ];
edge [ color = "#fcfcfc", penwidth =2, fontname = "helvetica Neue Ultra Light" ];
subgraph "clusterNftfiBundler" {
graph [ label = "NftfiBundler", color = "#445773", fontcolor = "#f0f0f0", style = "rounded", bgcolor = "#445773" ];
"NftfiBundler.<Constructor>" [ label = "<Constructor>", color = "#FF9797", fillcolor = "#FF9797" ];
"NftfiBundler.supportsInterface" [ label = "supportsInterface", color = "#FF9797", fillcolor = "#FF9797" ];
"NftfiBundler.permittedAsset" [ label = "permittedAsset", color = "#FF9797", fillcolor = "#FF9797" ];
"NftfiBundler.permittedErc20Asset" [ label = "permittedErc20Asset", color = "#FF9797", fillcolor = "#FF9797" ];
"NftfiBundler.buildBundle" [ label = "buildBundle", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"NftfiBundler.decomposeBundle" [ label = "decomposeBundle", color = "#ffbdb9", fillcolor = "#ffbdb9" ];
"NftfiBundler._receiveChild" [ label = "_receiveChild", color = "#f2c383", fillcolor = "#f2c383" ];
"NftfiBundler._receive1155Child" [ label = "_receive1155Child", color = "#f2c383", fillcolor = "#f2c383" ];
"NftfiBundler._receiveErc20Child" [ label = "_receiveErc20Child", color = "#f2c383", fillcolor = "#f2c383" ];
"NftfiBundler.INftfiHub" [ label = "INftfiHub" ];
"NftfiBundler.type" [ label = "type" ];
"NftfiBundler.IPermittedNFTs" [ label = "IPermittedNFTs" ];
"NftfiBundler.IPermittedERC20s" [ label = "IPermittedERC20s" ];
"NftfiBundler._safeMint" [ label = "_safeMint" ];
"NftfiBundler.IERC721" [ label = "IERC721" ];
"NftfiBundler._getChild" [ label = "_getChild" ];
"NftfiBundler._getERC20" [ label = "_getERC20" ];
"NftfiBundler.IERC1155" [ label = "IERC1155" ];
"NftfiBundler.ownerOf" [ label = "ownerOf" ];
"NftfiBundler._validateReceiver" [ label = "_validateReceiver" ];
"NftfiBundler._remove1155Child" [ label = "_remove1155Child" ];
"NftfiBundler.Transfer1155Child" [ label = "Transfer1155Child" ];
"NftfiBundler._removeChild" [ label = "_removeChild" ];
"NftfiBundler._oldNFTsTransfer" [ label = "_oldNFTsTransfer" ];
"NftfiBundler.TransferChild" [ label = "TransferChild" ];
"NftfiBundler._removeERC20" [ label = "_removeERC20" ];
"NftfiBundler.IERC20" [ label = "IERC20" ];
"NftfiBundler.TransferERC20" [ label = "TransferERC20" ];
}
subgraph "clusterERC998ERC20Extension" {
graph [ label = "ERC998ERC20Extension", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"ERC998ERC20Extension.supportsInterface" [ label = "supportsInterface" ];
"ERC998ERC20Extension._receiveChild" [ label = "_receiveChild" ];
"ERC998ERC20Extension._receive1155Child" [ label = "_receive1155Child" ];
"ERC998ERC20Extension._receiveErc20Child" [ label = "_receiveErc20Child" ];
}
subgraph "clusterINftfiHub" {
graph [ label = "INftfiHub", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"INftfiHub.getContract" [ label = "getContract" ];
}
subgraph "clusterIPermittedNFTs" {
graph [ label = "IPermittedNFTs", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"IPermittedNFTs.getNFTPermit" [ label = "getNFTPermit" ];
}
subgraph "clusterIPermittedERC20s" {
graph [ label = "IPermittedERC20s", color = "#e8726d", fontcolor = "#f0f0f0", style = "rounded,dashed", bgcolor = "#3b4b63" ];
"IPermittedERC20s.getERC20Permit" [ label = "getERC20Permit" ];
}
"NftfiBundler.<Constructor>";
"NftfiBundler.INftfiHub";
"NftfiBundler.supportsInterface";
"NftfiBundler.type";
"ERC998ERC20Extension.supportsInterface";
"NftfiBundler.permittedAsset";
"NftfiBundler.IPermittedNFTs";
"INftfiHub.getContract";
"IPermittedNFTs.getNFTPermit";
"NftfiBundler.permittedErc20Asset";
"NftfiBundler.IPermittedERC20s";
"IPermittedERC20s.getERC20Permit";
"NftfiBundler.buildBundle";
"NftfiBundler._safeMint";
"NftfiBundler.IERC721";
"NftfiBundler._getChild";
"NftfiBundler._getERC20";
"NftfiBundler.IERC1155";
"NftfiBundler.decomposeBundle";
"NftfiBundler.ownerOf";
"NftfiBundler._validateReceiver";
"NftfiBundler._remove1155Child";
"NftfiBundler.Transfer1155Child";
"NftfiBundler._removeChild";
"NftfiBundler._oldNFTsTransfer";
"NftfiBundler.TransferChild";
"NftfiBundler._removeERC20";
"NftfiBundler.IERC20";
"NftfiBundler.TransferERC20";
"NftfiBundler._receiveChild";
"ERC998ERC20Extension._receiveChild";
"NftfiBundler._receive1155Child";
"ERC998ERC20Extension._receive1155Child";
"NftfiBundler._receiveErc20Child";
"ERC998ERC20Extension._receiveErc20Child";
"NftfiBundler.<Constructor>" -> "NftfiBundler.INftfiHub" [ color = "#1bc6a6" ];
"NftfiBundler.supportsInterface" -> "NftfiBundler.type" [ color = "#1bc6a6" ];
"NftfiBundler.supportsInterface" -> "NftfiBundler.type" [ color = "#1bc6a6" ];
"NftfiBundler.supportsInterface" -> "ERC998ERC20Extension.supportsInterface" [ color = "white" ];
"NftfiBundler.permittedAsset" -> "NftfiBundler.IPermittedNFTs" [ color = "#1bc6a6" ];
"NftfiBundler.permittedAsset" -> "INftfiHub.getContract" [ color = "white" ];
"NftfiBundler.permittedAsset" -> "IPermittedNFTs.getNFTPermit" [ color = "white" ];
"NftfiBundler.permittedErc20Asset" -> "NftfiBundler.IPermittedERC20s" [ color = "#1bc6a6" ];
"NftfiBundler.permittedErc20Asset" -> "INftfiHub.getContract" [ color = "white" ];
"NftfiBundler.permittedErc20Asset" -> "IPermittedERC20s.getERC20Permit" [ color = "white" ];
"NftfiBundler.buildBundle" -> "NftfiBundler._safeMint" [ color = "#1bc6a6" ];
"NftfiBundler.buildBundle" -> "NftfiBundler.IERC721" [ color = "#1bc6a6" ];
"NftfiBundler.buildBundle" -> "NftfiBundler._getChild" [ color = "#1bc6a6" ];
"NftfiBundler.buildBundle" -> "NftfiBundler._getERC20" [ color = "#1bc6a6" ];
"NftfiBundler.buildBundle" -> "NftfiBundler.IERC1155" [ color = "#1bc6a6" ];
"NftfiBundler.decomposeBundle" -> "NftfiBundler.ownerOf" [ color = "#1bc6a6" ];
"NftfiBundler.decomposeBundle" -> "NftfiBundler._validateReceiver" [ color = "#1bc6a6" ];
"NftfiBundler.decomposeBundle" -> "NftfiBundler._remove1155Child" [ color = "#1bc6a6" ];
"NftfiBundler.decomposeBundle" -> "NftfiBundler.IERC1155" [ color = "#1bc6a6" ];
"NftfiBundler.decomposeBundle" -> "NftfiBundler.Transfer1155Child" [ color = "#1bc6a6" ];
"NftfiBundler.decomposeBundle" -> "NftfiBundler._removeChild" [ color = "#1bc6a6" ];
"NftfiBundler.decomposeBundle" -> "NftfiBundler.IERC721" [ color = "#1bc6a6" ];
"NftfiBundler.decomposeBundle" -> "NftfiBundler._oldNFTsTransfer" [ color = "#1bc6a6" ];
"NftfiBundler.decomposeBundle" -> "NftfiBundler.TransferChild" [ color = "#1bc6a6" ];
"NftfiBundler.decomposeBundle" -> "NftfiBundler._removeERC20" [ color = "#1bc6a6" ];
"NftfiBundler.decomposeBundle" -> "NftfiBundler.IERC20" [ color = "#1bc6a6" ];
"NftfiBundler.decomposeBundle" -> "NftfiBundler.TransferERC20" [ color = "#1bc6a6" ];
"NftfiBundler._receiveChild" -> "NftfiBundler.permittedAsset" [ color = "#1bc6a6" ];
"NftfiBundler._receiveChild" -> "ERC998ERC20Extension._receiveChild" [ color = "white" ];
"NftfiBundler._receive1155Child" -> "NftfiBundler.permittedAsset" [ color = "#1bc6a6" ];
"NftfiBundler._receive1155Child" -> "ERC998ERC20Extension._receive1155Child" [ color = "white" ];
"NftfiBundler._receiveErc20Child" -> "NftfiBundler.permittedErc20Asset" [ color = "#1bc6a6" ];
"NftfiBundler._receiveErc20Child" -> "ERC998ERC20Extension._receiveErc20Child" [ color = "white" ];
rankdir=LR
node [shape=plaintext]
subgraph cluster_01 {
label = "Legend";
key [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
<tr><td align="right" port="i1">Internal Call</td></tr>
<tr><td align="right" port="i2">External Call</td></tr>
<tr><td align="right" port="i3">Defined Contract</td></tr>
<tr><td align="right" port="i4">Undefined Contract</td></tr>
</table>>]
key2 [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
<tr><td port="i1"> </td></tr>
<tr><td port="i2"> </td></tr>
<tr><td port="i3" bgcolor="#445773"> </td></tr>
<tr><td port="i4">
<table border="1" cellborder="0" cellspacing="0" cellpadding="7" color="#e8726d">
<tr>
<td></td>
</tr>
</table>
</td></tr>
</table>>]
key:i1:e -> key2:i1:w [color="#1bc6a6"]
key:i2:e -> key2:i2:w [color="white"]
}
}
Halborn used automated testing techniques to enhance coverage of certain areas of the scoped contract. Among the tools used was Slither, a Solidity static analysis framework. After Halborn verified all the contracts in the repository and was able to compile them correctly into their ABI and binary formats. This tool can statically verify mathematical relationships between Solidity variables to detect invalid or inconsistent usage of the contracts' APIs across the entire code-base.
According to the test results, the findings found by these tools were considered false positives. All relevant findings were reviewed by the auditors, and relevant findings were addressed in the report as security concerns.
Halborn strongly recommends conducting a follow-up assessment of the project either within six months or immediately following any material changes to the codebase, whichever comes first. This approach is crucial for maintaining the project’s integrity and addressing potential vulnerabilities introduced by code modifications.
// Download the full report
* Use Google Chrome for best results
** Check "Background Graphics" in the print settings if needed