Dria

Swan
NFTHardhat
21,000 USDC
View results
Submission Details
Severity: medium
Invalid

Wrong calculation of round and roundTime in BuyerAgent::_computePhase()

Summary

Wrong calculation of round and roundTime in the BuyerAgent::_computePhase function.

Vulnerability Details

The BuyerAgent::_computePhase function is the function to compute the current round, phase and time until next phase w.r.t given market parameters.
Below is the function :

File: contracts/swan/BuyerAgent.sol#L308-L327
function _computePhase(SwanMarketParameters memory params, uint256 elapsedTime)
internal
pure
returns (uint256, Phase, uint256)
{
uint256 cycleTime = _computeCycleTime(params);
@--> uint256 round = elapsedTime / cycleTime;
@--> uint256 roundTime = elapsedTime % cycleTime;
// example:
// |-------------> | (roundTime)
// |--Sell--|--Buy--|-Withdraw-| (cycleTime)
if (roundTime <= params.sellInterval) {
return (round, Phase.Sell, params.sellInterval - roundTime);
} else if (roundTime <= params.sellInterval + params.buyInterval) {
return (round, Phase.Buy, params.sellInterval + params.buyInterval - roundTime);
} else {
return (round, Phase.Withdraw, cycleTime - roundTime);
}
}

Impact

As we can see on the highlighted lines, round and roundTime has been switched. This may lead to a wrong current round value and time until next phase value returned and a broader impact on the functions that directly or indirectly rely to BuyerAgent::_computePhase().

Tools Used

Manual Review.

Recommendations

File: contracts/swan/BuyerAgent.sol#L308-L327
function _computePhase(SwanMarketParameters memory params, uint256 elapsedTime)
internal
pure
returns (uint256, Phase, uint256)
{
uint256 cycleTime = _computeCycleTime(params);
-- uint256 round = elapsedTime / cycleTime;
-- uint256 roundTime = elapsedTime % cycleTime;
++ uint256 round = elapsedTime % cycleTime;
++ uint256 roundTime = elapsedTime / cycleTime;
// example:
// |-------------> | (roundTime)
// |--Sell--|--Buy--|-Withdraw-| (cycleTime)
if (roundTime <= params.sellInterval) {
return (round, Phase.Sell, params.sellInterval - roundTime);
} else if (roundTime <= params.sellInterval + params.buyInterval) {
return (round, Phase.Buy, params.sellInterval + params.buyInterval - roundTime);
} else {
return (round, Phase.Withdraw, cycleTime - roundTime);
}
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 8 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Appeal created

y0ng0p3 Submitter
8 months ago
inallhonesty Lead Judge
7 months ago
inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.