Omniscia AmpleSense Audit
Pioneer1Vault Manual Review Findings
Pioneer1Vault Manual Review Findings
PVT-01M: Redundant Execution Path
Type | Severity | Location |
---|---|---|
Logical Fault | Minor | Pioneer1Vault.sol:L55, L56, L60, L68 |
Description:
The _rebase
function will attempt to evaluate the optimal amount to sell via the trader
based on the AMPL balance's proximity to the CAP
threshold, however, an additional check is imposed beyond the sale that ensures the balance of the contract remains at or above the SELL_THRESHOLD
.
Example:
45function _rebase(uint256 old_supply, uint256 new_supply) internal override {46 require(address(trader) != address(0), "Pioneer1Vault: trader not set");47 uint256 new_balance = _ampl_token.balanceOf(address(this));48 require(new_balance > SELL_THRESHOLD, "Pioneer1Vault: Threshold isnt reached yet"); //needs to be checked or else _toSell fails49 if(new_supply > old_supply) {50 //only for positive rebases51 uint256 balance = _ampl_token.balanceOf(address(this));52
53 uint256 change_ratio_18digits = old_supply.mul(10**18).divDown(new_supply);54 uint256 surplus = new_balance.sub(new_balance.mul(change_ratio_18digits).divDown(10**18));55 uint256 to_sell = _toSell(surplus);56 _ampl_token.approve(address(trader), to_sell);57
58 trader.sellAMPLForEth(to_sell);59 //this checks that after the sale we're still above threshold60 require(_ampl_token.balanceOf(address(this)) >= SELL_THRESHOLD, "Pioneer1Vault: Threshold isnt reached yet");61 stakingContractEth.distribute{value : address(this).balance}(0, address(this));62 }63}64
65function _toSell(uint256 amount) internal view returns (uint256) {66 uint256 ampl_balance = _ampl_token.balanceOf(address(this));67 uint256 percentage = (END_PERCENT - START_PERCENT).mul(Math.min(ampl_balance, CAP).sub(SELL_THRESHOLD)).divDown(CAP.sub(SELL_THRESHOLD)) + START_PERCENT;68 return percentage.mul(amount).divDown(100);69}
Recommendation:
As the trader
can at most use the amount of tokens approved to it via the _toSell
calculation, we advise the _toSell
function itself to incorporate this limit and ensure the amount to sell is the minimum between percentage.mul(amount).divDown(100)
and _ampl_token.balanceOf(address(this)) - SELL_THRESHOLD
to ensure the require
check is not necessary and the code executes optimally at all times.
Alleviation:
The Amplesense considered this exhibit but opted not to apply a remediation for it in the current iteration of the codebase to avoid adjusting core contract logic at this point in the code's development.