orbland / contracts Goto Github PK
View Code? Open in Web Editor NEW๐ฎ Orb and related contracts. Auction + Harberger taxed ownership + invocations.
Home Page: https://orb.land
License: MIT License
๐ฎ Orb and related contracts. Auction + Harberger taxed ownership + invocations.
Home Page: https://orb.land
License: MIT License
The codebase makes extensive use of modifiers. There is room for consolidation and simplification to improve the readability of the codebase.
minimumBid()
, lastSettlementTime
, holderSolvent
, price()
, foreclosureTime
, cooldownRemaining
hasFunds
The modifiers onlyHolderSolvent
and onlyHolder
are always used together in the codebase. That indicates that they should not be different modifiers.
Simplify the codebase, remove the modifiers, and introduce onlySolventHolder
modifier that checks for both a) solvency and b) that msg.sender is the holder.
The codebase uses native ether. It's considered a bad practice for the following reasons:
fallback/receive
functionsPRBMath
A holder can flag the response to the question of a previous holder.
purchases
the Orb from Alice on the following day, day 1. He can call flagResponse
, and give the triggerId
of Alice's invocation.This is because all the following checks will pass:
if (!_responseExists(triggerId)) {
revert ResponseNotFound(triggerId);
}
if (block.timestamp - responses[triggerId].timestamp > RESPONSE_FLAGGING_PERIOD) {
revert FlaggingPeriodExpired(
triggerId, block.timestamp - responses[triggerId].timestamp, RESPONSE_FLAGGING_PERIOD
);
}
if (responseFlagged[triggerId] == true) {
revert ResponseAlreadyFlagged(triggerId);
}
flaggingEnd
trigger()
, add the following: flaggingEnd = block.timestamp + RESPONSE_FLAGGING_PERIOD;
flagResponse
check that: block.timestamp < flaggingEnd
purchase()
and foreclose()
add: flaggingEnd = block.timestamp
The function serves only as a getter. It's simpler to make the storage variable public
, thus removing the need of the function and simplifying the codebase.
The modifier is mainly used in external
functions, which by definition, can not be called by the contract. The only public
function that uses the modifier is lastSettlementTime,
where the modifier is used as a UX guardrail since the returned variable only makes sense if a user holds it. The orb. Removing the modifier would not affect the protocol in any way (as long as that function is concerned).
The modifier should be removed in an effort to simplify the codebase, as no real benefit rises from it's use.
Solmate offers a more gas efficient version of the ERC721 token than OpenZeppelin
Migrate the codebase to use Solmate
Currently purchase(uint256 currentPrice, uint256 newPrice)
checks that newPrice != 0
. This is not required, as the protocol can function as expected if newPrice = 0
, since the user can purchase the orb with a non zero new price and then set it to zero via setPrice(uint256 newPrice)
.
Remove the check
In _withdraw()
, we first check for sufficient funds before subtracting the amount to be withdrawn. This is not required as Solidity 0.8.X ships with underflow/overflow assurances. Thus, when removing from the mapping of the amount is larger than the available funds of the user, the subtraction will cause an underflow and will revert.
The check incurs gas costs without the need for it.
Remove the if clause at the start of the function
fundsOf
mapping can be public, without needing a specific user-defined getter function.
In finalizeAuction() the event emission is placed inside the if/else clause. That is not required and leads to duplicated code.
Move the event emission outside the if/else clause, at the end.
emit AuctionFinalized(winningBidder, winningBid);
startTime = 0;
endTime = 0;
The use of _msgSender() helper function by OpenZeppelin is not required, as the contract is not intended to be used with meta-transactions. It's more gas efficient to use msg.sender
.
Replace _msgSender()
with msg.sender
throughout the contract.
Removee onlyHolderHeld
if onlyHolder
and external
are present in the function.
Affected functions: setPrice
, exit
, flagResponse
.
After discussions with @lekevicius, we aligned on removing the requirement from the protocol side of transferring more funds than the bid amount and adding UI affordances to help the user calculate how much funds they have to transfer to support a bid for X amount of time.
The codebase does not have a CI/CD pipeline that runs the test suite against every new PR. That means that buggy code could be merged at some point and eventually be deployed.
Install a GitHub Action that runs the test suite against every new PR and every commit to main
.
The variable _price
is not required to be internal/private and have a public getter function. The modifiers in the function are used to enforce when price
should be called, as price
doesn't make sense in all the states of the smart contract (e.g when owned by the contract itself).
I suggest we remove the getter function and make the variable public. Interfaces and smart contracts built on top of the orb should know when price
makes sense and when it should not be read. This will remove unnecessary code from the smart cotnract.
When trigger()
is invoked by the holder, they can submit cleartext and hash, with cleartext being optional. The cleartext and contentHash need not to be stored.
The reason is that the storage happens so that there is an immutable record of that trigger and its question. It's a social contract. That means that storage is not required, but rather just the fact that the hash and/or cleartext was submitted.
That means that even if the hash were submitted as a calldata
argument without actually being used, the requirement for proof would be met with minimal gas implications. The calldata are part of the transaction and, thus, impossible to forge or alter.
Simply accept the data as calldata and emit the hash for ease of use by 3rd party apps and interfaces that build on top of the orb. The increment of the storage variable triggersCount
can happen in the event definition. triggersCount++
will return triggersCount
and then increment it.
function triggerText(string memory text) external onlyHolder onlyHolderSolvent {
if (block.timestamp < lastTriggerTime + COOLDOWN) {
revert CooldownIncomplete(lastTriggerTime + COOLDOWN - block.timestamp);
}
lastTriggerTime = block.timestamp;
emit Triggered(msg.sender, triggersCount++, keccak256(bytes(text)), block.timestamp);
}
function triggerHash(bytes32 contentHash) external onlyHolder onlyHolderSolvent
{
if (block.timestamp < lastTriggerTime + COOLDOWN) {
revert CooldownIncomplete(lastTriggerTime + COOLDOWN - block.timestamp);
}
lastTriggerTime = block.timestamp;
emit Triggered(msg.sender, triggersCount++, contentHash, block.timestamp);
}
A sophisticated user can perform the next attack after they become holders
of the orb and render the orb impossible to be bought by another person, while also keeping the orb's price to a minimum (even zero).
The user would need to set a relatively simple front-running bot that does the following:
purchase(oldPrice, newPrice)
purchase()
Then, the purchase(oldPrice, newPrice)
will always revert, as the oldPrice will have changed. By setting the price to something as small as 1*10e-18, the attacker can invalidate the purchase and, simultaneously, have a little economic cost ( in the context of the orb, the gas cost could be high). The attacked can do that and invalidate all purchase attempts while at the same time keeping themselves solvent (as the price is so low). Thus the issuer can never foreclose the orb and take back control.
It's worth noting that since the Orb has an essential element of a social contract, it doesn't mean that the attacked can reap the benefits of the Orb, as the issue can clearly see the attack and simply select to ignore any triggers
. The orb is more or less bricked, and thus, the attack is more of a grieving attack.
Finally, a white-hat hacker could attempt to front-run the attacker's bot and, by winning a gas auction, get their purchase()
transaction in front of the attacker's and thus unbrick
the orb.
Add a cooldown to set the price, for example, once per day:
uint256 cooldown;
function _setPrice(uint256 newPrice_) internal {
if(block.timestamp > cooldown){
cooldown = block.timestamp + 24 hours;
if (newPrice_ > MAX_PRICE) {
revert InvalidNewPrice(newPrice_);
}
uint256 oldPrice = _price;
_price = newPrice_;
emit NewPrice(oldPrice, newPrice_);
} else {
revert SetPriceCooldown;
}
}
The CEI pattern is a well-documented best practices approach that safeguards against vulnerabilities like reentrancies. Although no such vulnerability exists in the purchase()
function, it would be best to be changed, so the pattern is followed.
_transfer(holder, msg.sender, ERIC_ORB_ID);
_lastSettlementTime = block.timestamp;
_setPrice(newPrice);
emit Purchase(holder, msg.sender);
should be:
_lastSettlementTime = block.timestamp;
_setPrice(newPrice);
emit Purchase(holder, msg.sender);
_transfer(holder, msg.sender, ERIC_ORB_ID);
In line 416, the mapping is read and then copied to a memory variable. This is not required, as the value is only read once, thus it's more gas efficient to directly read from the mapping without declaring a memory variable in the first place.
uint256 totalFunds = _funds[_msgSender()] + msg.value;
When a user calls purchase, they input the currentPrice. It's cheaper to use the calldata input variable than the storage variable _price
throughout the function.
Replace_price
with currentPrice
triggerExists
can be simplified by simply checking the triggerCount
. In essence, the function can be removed altogether and be replaced by a simple check:
triggerId < triggerCount
If a triggerId is lower than the triggerCount, then the triggerId exists. Otherwise, it doesn't.
We can verify the fact by looking at trigger
and seeing that the count is incremented with every new invocation of trigger
. There is no other way for the counter to be incremented.
triggerId < triggerCount
In line 373, an addition is made that we know will never overflow. By adding unchecked { .. }
around it, we inform the compiler that it should not check for overflow, and thus, we save a tiny bit of gas.
unchecked {
return winning bid + MINIMUM_BID_STEP;
}
foreclosureTime
does not need to have an access modifier for the public getter and be internal. It's a UX guardrail that increases the codebase with no real protocol value.
Moreover, no need to check that _price
!= 0. If it's set to zero, it will simply revert.
INFINITY
Private variables make it very hard to inspect their state and thus test against them. It's best to use internal
as there is no difference for the grand majority of use-cases.
Replace private variables with internal.
In line 385, the memory variable is not required. We can save gas by removing it and doing the calculation directly in the return statement.
Remove the memory variable
No need to check for address(0) in fundsOf(). The returned data don't have any meaning in the context of the Orb, but it doesn't pose any danger to the protocol. The imposed gas cost on every invocation of fundsOf
, due to the check, can be avoided.
Remove the check
_settle()
does mainly two things:
effectiveFunds
of the holder and the owner_funds
mapping.It replicates the calculations inside effectiveFunds
, which can lead to a possible source of errors in the future if not handled carefully. Codepaths should be unique, especially in paths that do math calculations.
The codepaths should be unified. An example:
effectiveFundsOf
will be converted to public
instead of external
_settle()
will change as follows: function _settle() internal {
address holder = ERC721.ownerOf(ERIC_ORB_ID);
if (owner() == holder) {
return;
}
// Should never be reached if this contract holds the orb.
assert(address(this) != holder);
uint256 ownerEffective = effectiveFundsOf(owner());
uint256 transferableToOwner = _funds[owner()] - ownerEffective;
_funds[holder] = effectiveFundsOf(holder);
_funds[owner()] = ownerEffective;
_lastSettlementTime = block.timestamp;
emit Settlement(holder, owner(), transferableToOwner);
}
OZ ERC721 contract is excellent but could be more gas optimized, as it prioritizes guardrails above all. Moreover, the orb has some assumptions that render OZ default implementation moot, for example, the existence of only a single NFT. That means that we can have many gas optimization by simply not using a mapping to retrieve the owner of the NFT, but rather a simple storage variable address holder
.
By overriding ERC721 functions, we can create ERC721 compatible parts that are informed of these design characteristics of the Orb and thus make gas optimized informed decisions
| Solc version: 0.8.17 ยท Optimizer enabled: true ยท Runs: 1000 ยท Block limit: 30000000 gas โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Methods โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Contract ยท Method ยท Min ยท Max ยท Avg ยท # calls ยท usd (avg) โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท bid ยท 41100 ยท 95093 ยท 67659 ยท 14 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท closeAuction ยท 31728 ยท 154895 ยท 140405 ยท 17 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท deposit ยท 30221 ยท 47321 ยท 40607 ยท 8 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท exit ยท - ยท - ยท 82306 ยท 3 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท flagResponse ยท - ยท - ยท 82130 ยท 2 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท foreclose ยท - ยท - ยท 73049 ยท 4 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท purchase ยท 85135 ยท 109835 ยท 97018 ยท 12 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท recordTriggerCleartext ยท - ยท - ยท 59553 ยท 2 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท respond ยท 73092 ยท 73104 ยท 73098 ยท 4 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท setPrice ยท 33565 ยท 52802 ยท 44766 ยท 6 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท settle ยท 26021 ยท 46417 ยท 39618 ยท 6 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท startAuction ยท - ยท - ยท 76160 ยท 8 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท trigger ยท 108439 ยท 131627 ยท 114294 ยท 10 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท withdraw ยท 39992 ยท 58047 ยท 50309 ยท 7 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท withdrawAll ยท 35126 ยท 53181 ยท 39138 ยท 9 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Deployments ยท ยท % of limit ยท โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท - ยท - ยท 3265713 ยท 10.9 % ยท - โ
ยท------------------------------------------------------------|-------------|-------------|--------------|---------------|-------------ยท
ยท------------------------------------------------------------|---------------------------|--------------|-----------------------------ยท
| Solc version: 0.8.17 ยท Optimizer enabled: true ยท Runs: 1000 ยท Block limit: 30000000 gas โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Methods โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Contract ยท Method ยท Min ยท Max ยท Avg ยท # calls ยท usd (avg) โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท bid ยท 40859 ยท 94777 ยท 67386 ยท 14 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท closeAuction ยท 31604 ยท 129218 ยท 117734 ยท 17 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท deposit ยท 30083 ยท 47183 ยท 40433 ยท 8 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท exit ยท - ยท - ยท 56233 ยท 3 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท flagResponse ยท - ยท - ยท 81711 ยท 2 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท foreclose ยท - ยท - ยท 46986 ยท 4 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท purchase ยท 59044 ยท 83744 ยท 70927 ยท 12 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท recordTriggerCleartext ยท - ยท - ยท 59112 ยท 2 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท respond ยท 73092 ยท 73104 ยท 73098 ยท 4 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท setPrice ยท 32987 ยท 52224 ยท 44188 ยท 6 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท settle ยท 25737 ยท 46133 ยท 39334 ยท 6 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท startAuction ยท - ยท - ยท 76004 ยท 8 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท trigger ยท 108020 ยท 131208 ยท 113875 ยท 10 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท withdraw ยท 39854 ยท 57763 ยท 50088 ยท 7 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท withdrawAll ยท 34988 ยท 52897 ยท 38968 ยท 9 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Deployments ยท ยท % of limit ยท โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| contracts/EricOrb.sol:EricOrb ยท - ยท - ยท 2950829 ยท 9.8 % ยท - โ
ยท------------------------------------------------------------|-------------|-------------|--------------|---------------|-------------ยท
address public holder
_safeMint
with holder = address(this)
ERC721.ownerOf(ERIC_ORB_ID)
with holder
function tokenURI(uint256 tokenId) public view override returns (string memory) {
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string.concat(baseURI, "69") : "";
}
function _transfer(address, address to, uint256) internal override {
holder = to;
emit Transfer(from, to, ERIC_ORB_ID);
}
function ownerOf(uint256) public view virtual override returns (address) {
return holder;
}
function balanceOf(address owner) public view override returns (uint256) {
return owner == holder ? 1 : 0;
}
finalizeAuction doesn't need to check for contract ownership via the onlyContractHeld
modifier, since this is checked when the Auction starts. Thus, to get into the auction
state, the contract needs to own the orb.
Moreover, it's not possible to exit the auction
state without calling finalizeAuction()
. Thus it's impossible to change owners of the Orb before calling finalizeAuction()
Remove the modifier
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.