Submitted by ktg, also found by Kaysoft, dacian, kutugu, Co0nan, jnrlouis, and n1punp
https://github.com/code-423n4/2023-06-lybra/blob/main/contracts/lybra/token/EUSD.sol#L299-#L306 https://github.com/code-423n4/2023-06-lybra/blob/main/contracts/lybra/token/EUSD.sol#L414-#L418
Currently, the function EUSD.mint calls function EUSD.getSharesByMintedEUSD to calculate the shares corresponding to the input eUSD amount:
As you can see in the comment after sharesAmount is checked, //EUSD totalSupply is 0: assume that shares correspond to EUSD 1-to-1. The code assumes that if sharesAmount = 0, then totalSupply must be 0 and the minted share should equal to input eUSD. However, thats not always the case.
Variable sharesAmount could be 0 if totalShares *_EUSDAmount < totalMintedEUSD because this is integer division. If that happens, the user will profit by calling mint with a small EUSD amount and enjoys 1-1 minting proportion (1 share for each eUSD). The reason this can happen is because EUSD support burnShares feature, which remove the share of a users but keep the totalSupply value.
For example:
Below is POC for the above example. I use foundry to run tests; create a folder named test and save this to a file named eUSD.t.sol, then run it using command:
forge test --match-path test/eUSD.t.sol -vvvv
Manual Review
I recommend checking again in EUSD.mint function if sharesAmount is 0 and totalSupply is not 0, then exit the function without minting anything.
LybraFinance confirmed
