First depositor Issue
Description
The first depositor issue exists in the context of bond
, as the amount of tokens received is determined by the exchange rate of the supply and the amount to be bonded. This is compounded by the existence of the donate
functionality, which allows for the inflation of share prices.
pub(crate) fn compute_mint_amount(
ustake_supply: Uint128,
utoken_to_bond: Uint128,
current_delegations: &[Delegation],
) -> Uint128 {
let utoken_bonded: u128 = current_delegations.iter().map(|d| d.amount).sum();
if utoken_bonded == 0 {
utoken_to_bond
} else {
ustake_supply.multiply_ratio(utoken_to_bond, utoken_bonded)
}
}
Impact
When a new platform is launched, a malicious attacker could mint one share, and when another user attempts to bond, the transaction can be front-run with the donation
functionality to inflate the share price, leading to a truncation in the calculations. Consequently, the user attempting to bond will not receive their bonded tokens as expected.
Recommendations
Add a check to ensure that the user gets more than zero shares or add an option that allows a user to ensure they get a minimum amount of shares (slippage check).
Remediation
While this issue does not affect the currently deployed contracts, as it exists only during the initial state of the pool, the Silo team acknowledged the finding and implemented a fix in the commit .
We understand that the fix does not fully mitigate the issue and have recommended to the team to use a small amount of seed liquidity for future deployments of similar contracts. The Silo team has agreed to use seed liquidity for upcoming deployments, effectively mitigating potential similar issues in future deployments.