51296 sc low arctokenpurchase withdrawal breaks view functions
Submitted on Aug 1st 2025 at 14:11:09 UTC by @funkornaut for Attackathon | Plume Network
Report ID: #51296
Report Type: Smart Contract
Report severity: Low
Target: https://github.com/immunefi-team/attackathon-plume-network/blob/main/arc/src/ArcTokenPurchase.sol
Impacts:
Contract fails to deliver promised returns, but doesn't lose value
Description
Brief/Intro
The withdrawUnsoldArcTokens() function in ArcTokenPurchase.sol contains an accounting logic error that causes multiple view functions (getMaxNumberOfTokens() and getTokenInfo()) to return incorrect values after admin withdrawals. When token administrators withdraw unsold tokens, the function correctly transfers the tokens but fails to update the internal sale accounting, leading to persistent discrepancies between reported and actual token availability.
Vulnerability Details
The vulnerability exists because withdrawUnsoldArcTokens() only performs the token transfer without updating the TokenInfo accounting:
function withdrawUnsoldArcTokens(
address _tokenContract,
address to,
uint256 amount
) external onlyTokenAdmin(_tokenContract) {
// ... validation checks ...
ArcToken token = ArcToken(_tokenContract);
uint256 contractBalance = token.balanceOf(address(this));
if (contractBalance < amount) {
revert InsufficientUnsoldTokens();
}
bool success = token.transfer(to, amount); // Transfers tokens
if (!success) {
revert ArcTokenWithdrawalFailed();
}
// MISSING: TokenInfo accounting update
// Should include: info.totalAmountForSale -= amount;
}Meanwhile, both affected view functions rely on the unupdated accounting:
TokenInfo Struct Corruption:
Impact Details
When an admin withdraws Arc tokens and there is an ongoing arc token sale the view functions to get token info and the max number of tokens available for purchase will be incorrect. This may cause issues with user facing front end and overall user experience.
References
https://github.com/immunefi-team/attackathon-plume-network/blob/main/arc/src/ArcTokenPurchase.sol#L419-#L429 https://github.com/immunefi-team/attackathon-plume-network/blob/main/arc/src/ArcTokenPurchase.sol#L359-#L363 https://github.com/immunefi-team/attackathon-plume-network/blob/main/arc/src/ArcTokenPurchase.sol#L347-#L350
Link to Proof of Concept
https://gist.github.com/Funkornaut/cd3844097890ece413201eba6ef6ff4a
Proof of Concept
Was this helpful?