erc404's People
Forkers
zyi10 0x8400 mathdroid anditsmd32 9cat 0xmillz web3flyer fofcool generationvine headria soullight free-yourself arcology-network iamjedi888 dyt9qc sekmet kennisnutz chtoken 0xmeow404 ahmetson illjewminati blake-shuttle magic990619 tomdecentral unidecentralart jackgryder sahilkharya ate-bit-dave 0x25c 0xgizmob rapture-maxed namesreallyblank raeyanp dinolabs fastackl gisteroxcaptail goldenreader-c nftgo lingshenji monyverse number1jewel56broodsee l-readyna billite-jiggyough soundnsmilefibrouppl bombmoney limetaryd doodlepenguink interiorit12 eculdsayinertle bugsliglobays paul-klan dinolabs roninercx muroko yanxg zeus-labs-org scopency93 p-dealwis letsuchem-l solidityworks hunterskunky-37 questan-t adsorcept78matterva cryptomaggic 23deltatana precisetheborg-i commentsben3 xadsorcept iparkelratchapter septorch51 maelowizard ph0enixxx dkovinic sletsuchem gsfuture narcommaf2 goober86 0xted97 tonihil aarav2402 alimansouri13 ladywib wwwaldo zhoujielun118 872409 gmjgh pulsitronx dogaoztuzun hironate cryptoarthk 0xdev404 wozhendeai cromatikap yuhuajing oxmrrobot westonnelson yu23ki14 huostarter jennkalidoss elacityerc404's Issues
What happens if allowance goes negative?
From the transferFrom
method, the line 235
if (allowed != type(uint256).max) {
allowance[from_][msg.sender] = allowed - value;
}
Should there be a check to ensure value < allowed, and revert if so?
Any plan to submit this 404 standard to the EIPs repo?
I'm curious whether Pandora team plans to submit this hybrid ERC20+ERC721 standard to the EIPs repository. Currently, there's some confusion about the final function interfaces and events, as well as the rationale behind them (some of which have changed from the legacy implementation). Without an official standard, it becomes particularly challenging for other projects to, for instance, implement their own 404 smart contracts with different performance tradeoffs while ensuring consistency with the specification. Also difficult for wallets, indexers and exchanges to know what data to read.
In the current codebase, the event Transfer(...)
and event Approval(...)
have been completely removed. Do we expect Etherscan, wallets, and other indexers to track the new ERC20Transfer
, ERC20Approval
, ERC721Transfer
, etc., events? Otherwise I don't think token balances won't show on Web3 wallets / and contract won't be recognized as token on Etherscan.
I'm willing to assist with the draft if there are plans to proceed. Any information would be greatly appreciated.
transferFrom potential vulnerability?
Seems like a bit of an oversight, or perhaps I’m not seeing the protection mechanisms. I’m noticing the transferFrom function uses “amountOrId” as an input. Could NFTs theoretically be stolen from liquidity providers? A DEX using the approve and transferFrom function to perform swaps means if a user buys a low enough amount of token they could theoretically trigger an ERC721 transfer instead of an ERC20 transfer. In fact anyone using the approve method for any ERC20 amount is susceptible to this type of attack.
For example if I buy 1000 wei (0.000000000000001 ERC20) I could theoretically steal NFT #1000 if it’s being provided by a liquidity provider on a DEX using approve and transferFrom. Not sure which, if any, DEXes use this method for swaps. It’s just the matter of finding out who provides liquidity, which token IDs they own and buying exactly those amounts of ERC20 wei. I did notice a whitelist but I assume that will only work if the white listed exchange or contract holds the token instead of facilitating the swap.
Thoughts?
This is purely a technical question and in no way am I encouraging to attempt this on live projects. I’ll be writing some hardhat tests to share later testing my assumptions on a VM.
High ID Numbers Encoded
Hello,
I've just tested the new version and it's working very well. However, I have a question regarding the ID encoding system.
I've noticed that the ID encoding system generates quite high numbers. I understand there might be technical reasons behind this decision, but I'd like to know if it's absolutely necessary to keep these values so high.
Would it be possible to configure or edit the encoding system to start the ID sequence from a lower number, such as 1, to have IDs like 1, 2, 3, 4, etc.? This would make management and tracking much easier for my specific use case.
Thank you for your attention, and I look forward to your response.
Ditch whitelist in favor of opt-in
Opportunity
Maintaining a whitelist amidst an unpredictable sea of DEXs and DEX aggregators seems untenable. It certainly isn't "decentralized" and also ties the contract creator to a responsibility they could do without in their lives.
Solution
Instead, why not allow or indeed require wallets to opt-in to NFT mint/burning aspect of 404's? This could be done prior to any engagement with the 404 contract or after-the-fact, minting as many NFTs as their current balance permits.
If opting in is a one-way process — not able to be reversed — then all other functionality and tokenomics are retained for all users.
Efficiency
There is a gas cost in having the contract maintain this list of opt-ins, which will in most cases be considerably larger in size than the existing whitelist scheme. (You could have both, I suppose, with opt-ins overriding the whitelist for security/trust reasons.) The extra SSTOR cost might be optimized by packing groups of 256 accounts into single bit binary boolean's — 256 opt-ins stored in a single storage slot — based on your now deterministic NFT token IDs — though that implies that a holder must have at least NFT to be opted in. Just a thought.
Conclusion
You're welcome. :p
gruv0r
Consider ERC1155?
Has anyone considered this would be better with ERC1155, as it has batchTransfers, different function signatures it would be way better for blending ERC20, afterall, ERC1155 is designed for multiple tokens. I wrote my own version of "ERC404" using ERC1155, feel free to check it out or use it: https://github.com/TechnicallyWeb3/TW3404
zsh: parse error near `}'
I am a new learner here. I am trying to do a Quickstart in your latest tutorial and everything works fine installing forge etc. when I get to the step that runs the example code I get an error at the end zsh: parse error near `}':
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {ERC404} from "erc404/ERC404.sol";
contract ExampleERC404 is Ownable, ERC404 {
constructor(
string memory name_,
string memory symbol_,
uint8 decimals_,
uint256 maxTotalSupplyERC721_,
address initialOwner_
) ERC404(name_, symbol_, decimals_) Ownable(initialOwner_) {
setERC721TransferExempt(initialOwner, true);
mintERC20(initialOwner, maxTotalSupplyERC721_ * units, false);
}
function tokenURI(uint256 id_) public pure override returns (string memory) {
return string.concat("https://example.com/token/", Strings.toString(id_));
}
function setERC721TransferExempt(address account_, bool value_) external onlyOwner {
setERC721TransferExempt(account, value_);
}
}
zsh: parse error near `}'
How do I get around this problem? I have tried reinstalling zsh with homebrew. still the same. sorry if this is basic stuff but I searched the internet everywhere and can't find a straight answer.
No `Transfer` event emitted in new ERC404 implementation / unresolved ERC20 <> ERC721 spec collision
The Transfer
event was emitted in the legacy version ==> https://github.com/Pandora-Labs-Org/erc404-legacy/blob/master/src/ERC404.sol#L80-L84
But it is not emitted in the latest version
This event is an ERC-20 and ERC-721 standard event so it is likely to cause issues with platforms like OpenSea and Etherscan that expect this event to fire on transfer
You can see this issue manifesting on Etherscan here ==> https://etherscan.io/tx/0xb7e3fbc0f77cc31fe0536e2456dea7cc6ee0c5cf2db46276b6e98457ac7d5311
Closely related to this is that there is a collision between ERC20 and ERC721 in the Transfer
event because they both are supposed to emit it
The solution that Pandora seems to have come to in its deployed version is that only transfers that trigger an ERC721 transfer emit the Transfer
event e.g. ==> https://etherscan.io/tx/0xc1c0bdd6169338d02b8ab393620f5b62bc2dc0419bb53e81b75c41d6225dc5ad
In other words, Transfer
events are only emitted for ERC-721
This means for example for this holder, etherscan can "see" the ERC-721 transfers: https://etherscan.io/address/0x8febbf7c0b133f746f9303deff1191334d1a0ae5#nfttransfers
But it can't "see" the ERC-20 transfers: https://etherscan.io/address/0x8febbf7c0b133f746f9303deff1191334d1a0ae5#tokentxns
Issue with NFT
Hi,
we've deployed this new version of the contract but seems like there might be an issue with NFTs? Some users buying the token using Uniswap but do not see any NFT.
Etherscan link: https://etherscan.io/address/0x009bfab2a411d32954a180ae1c1e61d2cc43a4ac
Contract address: 0x009bfab2a411d32954a180ae1c1e61d2cc43a4ac
Making ERC404 `_storedERC721Ids` internal
What:
By making _storedERC721Ids
in ERC404 internal instead of private, it allows access of the dequeue by 404 extensions without having to edit the core ERC404.sol, and by developers without having to load the state manually. Currently, ERC404 only exposes the length
of the dequeue in erc721TokensBankedInQueue()
.
Why + Example:
An example of an extension that would benefit from this change is a ERC404Viewable.sol
. This would expose the queue on the contract api level, lowering the bar for developers who want to access that state. This would make arbitrage of specific 721 ids from the dequeue more accessible for defi power users / devs in general to participate
What would be the preferred to to ducktype if a contract is a 404?
For indexers of all sorts it's useful to be able to 'somewhat reliably' be able to ducktype if a contract is a 404.
What would be the preferred way here?
Upgradable Proxy for ERC404
Hi, ERC404 Folks,
I think it is necessary to make new Upgradable Proxy for ERC404, and time is up because it's enough to be famous in ever-evolving developing filed.
Beginning from basic Upgradable Proxy(TUDP) or forking UDP/Diamond, whatever we approach, it's time to make suitable proxy contract for ERC404 to make more usable.
An error in erc20TransferFrom() function
If the 'from_' is the msg.sender, it don't need to check the allowance of the 'from_'. Otherwise it will throw a revert error.
function erc20TransferFrom(
address from_,
address to_,
uint256 value_
) public virtual returns (bool) {
// Prevent minting tokens from 0x0.
if (from_ == address(0)) {
revert InvalidSender();
}
// Prevent burning tokens to 0x0.
if (to_ == address(0)) {
revert InvalidRecipient();
}
uint256 allowed = allowance[from_][msg.sender];
// Check that the operator has sufficient allowance.
if (allowed != type(uint256).max) {
allowance[from_][msg.sender] = allowed - value_;
}
// Transferring ERC-20s directly requires the _transferERC20WithERC721 function.
// Handles ERC-721 exemptions internally.
return _transferERC20WithERC721(from_, to_, value_);
}
I have modified the following code
function erc20TransferFrom(
address from_,
address to_,
uint256 value_
) public virtual returns (bool) {
// Prevent minting tokens from 0x0.
if (from_ == address(0)) {
revert InvalidSender();
}
// Prevent burning tokens to 0x0.
if (to_ == address(0)) {
revert InvalidRecipient();
}
if (from_ != msg.sender) {
uint256 allowed = allowance[from_][msg.sender];
// Check that the operator has sufficient allowance.
if (allowed != type(uint256).max) {
allowance[from_][msg.sender] = allowed - value_;
}
}
// Transferring ERC-20s directly requires the _transferERC20WithERC721 function.
// Handles ERC-721 exemptions internally.
return _transferERC20WithERC721(from_, to_, value_);
}
transferFrom is not working (for NFT transfer)
Using transferFrom for the NFT transfer is reverting due to the shl modification.
await contract.write.transferFrom([walletA.account.address, walletB.account.address, 12n], { account: walletA.account.address })
The shl fix made, is not working.
function _getOwnedIndex(
uint256 id_
) internal view virtual returns (uint256 ownedIndex_) {
uint256 data = _ownedData[id_];
assembly {
ownedIndex_ := shl(data, 160)
}
}
function _setOwnedIndex(uint256 id_, uint256 index_) internal virtual {
uint256 data = _ownedData[id_];
if (index_ > _BITMASK_OWNED_INDEX >> 160) {
revert OwnedIndexOverflow();
}
assembly {
data := add(
and(data, _BITMASK_ADDRESS),
and(shl(index_, 160), _BITMASK_OWNED_INDEX)
)
}
_ownedData[id_] = data;
}
With my example i got (before the shl fix):
Before transfer:
WalletA [
11n, 12n, 13n, 14n,
15n, 16n, 17n, 18n,
19n, 20n
]
WalletB []
After transfer:
WalletA [
20n, 12n, 13n,
14n, 15n, 16n,
17n, 18n, 19n
]
WalletB[ 12n ]
As we can see, there is a duplicate 12n and the 11n is removed
Any plan to submit to NPM like @openzeppelin ?
We hope pandora to submit it on NPM for make development easier for other dev adopt this standard.
Enable support of ERC-721 and ERC-20 into ERC-165 compliance
As far as know, this contract type is intended to behaves as ERC-721 and ERC-20, maybe it would be better to these both standard in the supportsInterface
method
Line 426 in e78af83
enhance {_setOwnedIndex} to reduce the gas consumption
Issue
There is a useless assembly operation in the data packing of internal function {_setOwnedIndex}:
function _setOwnedIndex(uint256 id_, uint256 index_) internal virtual {
...
assembly {
data := add(
and(data, _BITMASK_ADDRESS),
// shl(160, index_) makes sure all 0 in the low 160 bits so that `and(xxx, _BITMASK_OWNED_INDEX)` is needless
and(shl(160, index_), _BITMASK_OWNED_INDEX)
)
}
_ownedData[id_] = data;
}
I have run the test with my modification and it actually reduces the gas:
·-------------------------------------------------|----------------------------|-------------|-----------------------------·
| Solc version: 0.8.20 · Optimizer enabled: false · Runs: 200 · Block limit: 30000000 gas │
··················································|····························|·············|······························
| Methods │
··················|·······························|·············|··············|·············|···············|··············
| Contract · Method · Min · Max · Avg · # calls · usd (avg) │
··················|·······························|·············|··············|·············|···············|··············
| ERC404Example · setApprovalForAll · 24773 · 46685 · 40424 · 7 · - │
··················|·······························|·············|··············|·············|···············|··············
| ERC404Example · setERC721TransferExempt · 29287 · 204448 · 94214 · 5 · - │
··················|·······························|·············|··············|·············|···············|··············
| ERC404Example · setSelfERC721TransferExempt · 27026 · 46333 · 36680 · 2 · - │
··················|·······························|·············|··············|·············|···············|··············
| ERC404Example · transfer · 32509 · 5034556 · 385571 · 21 · - │
··················|·······························|·············|··············|·············|···············|··············
| MinimalERC404 · approve · 27039 · 51490 · 46518 · 13 · - │
··················|·······························|·············|··············|·············|···············|··············
| MinimalERC404 · mintERC20 · 43161 · 5058633 · 1717416 · 17 · - │
··················|·······························|·············|··············|·············|···············|··············
| MinimalERC404 · permit · 76946 · 77318 · 77132 · 4 · - │
··················|·······························|·············|··············|·············|···············|··············
| MinimalERC404 · safeTransferFrom · 130010 · 132655 · 131773 · 3 · - │
··················|·······························|·············|··············|·············|···············|··············
| MinimalERC404 · setApprovalForAll · 46584 · 46596 · 46590 · 2 · - │
··················|·······························|·············|··············|·············|···············|··············
| MinimalERC404 · setERC721TransferExempt · 49209 · 3205288 · 1451911 · 9 · - │
··················|·······························|·············|··············|·············|···············|··············
| MinimalERC404 · transfer · 59231 · 261414 · 120135 · 13 · - │
··················|·······························|·············|··············|·············|···············|··············
| MinimalERC404 · transferFrom · 58908 · 129681 · 103574 · 13 · - │
··················|·······························|·············|··············|·············|···············|··············
| Deployments · · % of limit · │
··················································|·············|··············|·············|···············|··············
| ERC404Example · - · - · 4135940 · 13.8 % · - │
··················································|·············|··············|·············|···············|··············
| ERC404ExampleUniswapV2 · - · - · 4205985 · 14 % · - │
··················································|·············|··············|·············|···············|··············
| ERC404ExampleUniswapV3 · - · - · 4334783 · 14.4 % · - │
··················································|·············|··············|·············|···············|··············
| MinimalERC404 · - · - · 4038373 · 13.5 % · - │
··················································|·············|··············|·············|···············|··············
| MockInvalidERC721Receiver · - · - · 198533 · 0.7 % · - │
··················································|·············|··············|·············|···············|··············
| MockValidERC721Receiver · - · - · 193569 · 0.6 % · - │
·-------------------------------------------------|-------------|--------------|-------------|---------------|-------------·
centralize validValueOrId check
just an idea, not needed for this version: this logic could be a function since we reuse it everywhere, it's critical, and when we want to support burning it will need to be changed in many places.
Originally posted by @caldereth in #17 (comment)
DRAFT: Fail to retrieve from bank when transferring fractional to self
Traces:
Traces:
[3813425] Erc404MinimalTest::test_erc721Storage_retrieveFromBank(76, 0xd38171555580273cEa88FA0cD3622F9bb94a236B, 0xd38171555580273cEa88FA0cD3622F9bb94a236B)
├─ [0] VM::assume(true) [staticcall]
│ └─ ← ()
├─ [0] VM::assume(true) [staticcall]
│ └─ ← ()
├─ [0] VM::assume(true) [staticcall]
│ └─ ← ()
├─ [2587] MinimalERC404::whitelist(0xd38171555580273cEa88FA0cD3622F9bb94a236B) [staticcall]
│ └─ ← false
├─ [587] MinimalERC404::whitelist(0xd38171555580273cEa88FA0cD3622F9bb94a236B) [staticcall]
│ └─ ← false
├─ [0] VM::assume(true) [staticcall]
│ └─ ← ()
├─ [0] VM::prank(0x0000000000000000000000000000000000000001)
│ └─ ← ()
├─ [3771449] MinimalERC404::mintERC20(0xd38171555580273cEa88FA0cD3622F9bb94a236B, 76000000000000000000 [7.6e19], true)
│ ├─ emit ERC20Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, amount: 76000000000000000000 [7.6e19])
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 1)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 2)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 3)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 4)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 5)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 6)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 7)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 8)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 9)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 10)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 11)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 12)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 13)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 14)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 15)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 16)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 17)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 18)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 19)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 20)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 21)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 22)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 23)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 24)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 25)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 26)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 27)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 28)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 29)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 30)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 31)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 32)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 33)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 34)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 35)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 36)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 37)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 38)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 39)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 40)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 41)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 42)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 43)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 44)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 45)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 46)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 47)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 48)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 49)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 50)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 51)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 52)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 53)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 54)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 55)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 56)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 57)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 58)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 59)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 60)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 61)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 62)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 63)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 64)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 65)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 66)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 67)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 68)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 69)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 70)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 71)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 72)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 73)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 74)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 75)
│ ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 76)
│ └─ ← ()
├─ [0] VM::prank(0xd38171555580273cEa88FA0cD3622F9bb94a236B)
│ └─ ← ()
├─ [42702] MinimalERC404::transfer(0xd38171555580273cEa88FA0cD3622F9bb94a236B, 100000000000000000 [1e17])
│ ├─ emit ERC20Transfer(from: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, amount: 100000000000000000 [1e17])
│ ├─ emit ERC721Transfer(from: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, to: 0x0000000000000000000000000000000000000000, id: 76)
│ └─ ← true
├─ [2608] MinimalERC404::balanceOf(MinimalERC404: [0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f]) [staticcall]
│ └─ ← 0
├─ [463] MinimalERC404::erc721TokensBankedInQueue() [staticcall]
│ └─ ← 1
├─ [0] VM::expectEmit(false, false, false, false)
│ └─ ← ()
├─ emit ERC20Transfer(from: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, amount: 100000000000000000 [1e17])
├─ [0] VM::expectEmit(false, false, false, false)
│ └─ ← ()
├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 76)
├─ [0] VM::prank(0xd38171555580273cEa88FA0cD3622F9bb94a236B)
│ └─ ← ()
├─ [26782] MinimalERC404::transfer(0xd38171555580273cEa88FA0cD3622F9bb94a236B, 100000000000000000 [1e17])
│ ├─ emit ERC20Transfer(from: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, amount: 100000000000000000 [1e17])
│ ├─ emit ERC721Transfer(from: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, to: 0x0000000000000000000000000000000000000000, id: 75)
│ └─ ← true
├─ [606] MinimalERC404::erc20BalanceOf(0xd38171555580273cEa88FA0cD3622F9bb94a236B) [staticcall]
│ └─ ← 76000000000000000000 [7.6e19]
├─ [715] MinimalERC404::ownerOf(76) [staticcall]
│ └─ ← "NotFound()"
└─ ← "NotFound()"
```
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.