Althea Liquid Infrastructure
• JrNet • 25 min readThe code under review can be found in 2024-02-althea-liquid-infrastructure.
Find my analysis report here: Tagged as sufficient quality report
[M-01] Function distribute
can be paused by owner of the contract
Function distribute
is used to pay out rewards in LiquidInfrastructureERC20 contract. When distribution started users are prevented from performing transfers, mints, and burns i.e., no token holder is allowed to burn the tokens to claim their tokens / transfer their erc20 tokens to others. This implies that completion of distribution is crucial step.
But owner of the contract is allowed to change the distributableERC20s
which is looped over to send the entitlement amt to recipient. If a owner managed to set a token which contract doesn't hold balance for it reverts and never completes.
Function distribute
is used to pay out rewards in LiquidInfrastructureERC20 contract. When distribution started users are prevented from performing transfers, mints, and burns i.e., no token holder is allowed to burn the tokens to claim their tokens / transfer their erc20 tokens to others. This implies that completion of distribution is crucial step.
But owner of the contract is allowed to change the distributableERC20s
which is looped over to send the entitlement amt to recipient. If a owner managed to set a token which contract doesn't hold balance for it reverts and never completes.
Impact
Reward distribution never completes results in halting all the functionalities of token holders resulting in financial loss.
Proof of Concept
- A LiquidInfrastructureERC20 is deployed with tokens
distributableERC20s = [A,B,C]
andMinDistributionPeriod = 500
- Users look at potential reward opportunity and mints the LiquidInfrastructure tokens.
- Owner invokes function
distribute(1)
(1 -> numDistributions). - This locks the contract, calculates the entitlement and distributes the entitlement tokens to first holder.
- Passing the MinDistributionPeriod owner sets
distributableERC20s = [D,B,C]
(it is not protected).
- When other users try to call distribute, the values in
erc20EntitlementPerUnit
are cached for tokens [A,B,C] - The entitlement calculated for token D will be (0.5 (cached entitlement value of token A) * 10 (balanceof LiquidInfrastructure tokens ) = 5e17 suppose)
- This will lock the contract permanently.
Tools Used
Manual Code review
Recommended Mitigation Steps
Halt setDistributableERC20s
during distribution