ERC20TokenEmitter will not work after a certain period of time
mediumLines of code
Vulnerability details
Impact
The timeSinceStart in the vrgdac.xToY function will revert over a certain value, resulting in the ERC20TokenEmitter#buyToken function always revert.
Proof of Concept
Initialize the VRGDAC using the parameters in the test code.
solidityVRGDAC vrgdac = new VRGDAC(1 ether, 1e18 / 10, 1_000 * 1e18);
The timeSinceStart is set to 394 days in the test code:
solidityfunction testVRGDAC_time() public { VRGDAC vrgdac = new VRGDAC(1 ether, 1e18 / 10, 1_000 * 1e18); int256 x = vrgdac.yToX({ timeSinceStart: toDaysWadUnsafe(86400 * 400), sold: 1000 ether, amount: 1 ether }); uint256 xx = uint256(x); console.log(xx + 1); console.log(xx / 1e18); }
Run the forge test -vvvv, console to output:
[FAIL. Reason: UNDEFINED] testVRGDAC_time() (gas: 554525)
Traces:
[106719] CounterTest::setUp()
├─ [49499] → new Counter@0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f
│ └─ ← 247 bytes of code
├─ [2390] Counter::setNumber(0)
│ └─ ← ()
└─ ← ()
[554525] CounterTest::testVRGDAC_time()
├─ [517512] → new VRGDAC@0x2e234DAe75C793f67A35089C9d99245E1C58470b
│ └─ ← 2578 bytes of code
├─ [3617] VRGDAC::yToX(400000000000000000000, 1000000000000000000000, 1000000000000000000) [staticcall]
│ └─ ← "UNDEFINED"
└─ ← "UNDEFINED"
Changing the timeSinceStart to toDaysWadUnsafe(86400 * 365) will work.
When this function is used in ERC20TokenEmitter#buyToken, the timeSinceStart is: block.timestamp-startTime
solidityfunction buyTokenQuote(uint256 amount) public view returns (int spentY) { require(amount > 0, "Amount must be greater than 0"); return vrgdac.xToY({ timeSinceStart: toDaysWadUnsafe(block.timestamp - startTime), sold: emittedTokenWad, amount: int(amount) }); }
startTime is set during the initialization of the ERC20TokenEmitter contract:
solidityfunction initialize( address _initialOwner, address _erc20Token, address _treasury, address _vrgdac, address _creatorsAddress ) external initializer { ..... startTime = block.timestamp; }
In other words, if the ERC20TokenEmitter contract is deployed and initialized and becomes unavailable after 400 days(400 days is the test value, the actual value will be affected by other parameters), calling the buyToken function will always revert.
Tools Used
vscode manual
Recommended Mitigation Steps
Optimize the vrgdac.yToX function, or set a minimum timeSinceStart value, which is used when the minimum is exceeded.
Assessed type
Math
