Platform: Code4rena
Start Date: 23/02/2024
Pot Size: $36,500 USDC
Total HM: 2
Participants: 39
Period: 7 days
Judge: Dravee
Id: 338
League: ETH
Rank: 38/39
Findings: 1
Award: $19.59
π Selected for report: 0
π Solo Findings: 0
π Selected for report: SBSecurity
Also found by: 0xDemon, 0xLuckyLuke, 14si2o_Flint, ArmedGoose, DarkTower, Shubham, Tigerfrake, cheatc0d3, peanuts, sl1
19.5868 USDC - $19.59
Users can initiate redemptions regardless of the maturity status of the shares. This violates the expected behavior specified in EIP-5095
, which recommends redemptions only after maturity.
The function PrincipalToken::_beforeRedeem
allows users to redeem shares without considering maturity, which contradicts EIP-5095
standard behavior which is mentioned in the following:
https://eips.ethereum.org/EIPS/eip-5095 "PTs mature at a precise second, but given the reactive nature of smart contracts, there canβt be an event marking maturity, because there is no guarantee of any activity at or after maturity. Emitting an event to notify of maturity in the first transaction after maturity would be imprecise and expensive. Instead, integrators are recommended to either use the first Redeem event, or to track themselves when each PT is expected to have matured."
Off-chain information may be inaccurate as redemptions can occur before maturity, leading to potential misinformation. Contradicts standard behavior, potentially causing confusion among users and integrators.
Manual Review
Implement maturity checks to ensure redemptions occur only after maturity, adhering to the EIP-5095
standard. Enhance off-chain communication to provide accurate information regarding redemption eligibility and maturity status.
The PrincipalToken::updateYield
function returns the updated user yield.
function beforeYtTransfer(address _from, address _to) external override { if (msg.sender != yt) { revert UnauthorizedCaller(); } updateYield(_from); updateYield(_to); }
VScode
Consider checking the return value to be valid.
Simplified Token Handling: The _token parameter in the flashLoan function seems unnecessary since the token address (ibt) remains constant throughout the function. Removing this parameter would streamline the interface.
Efficient Loan Calculation: The maxFlashLoan function accurately determines the maximum loan amount based on the contract's token balance, returning 0 if the token address differs from ibt.
Secure Fee Computation: The flashFee function calculates fees exclusively for the designated token (ibt) and ensures safety by reverting with an AddressError if the provided token address doesn't match.
Overall: The functions demonstrate clear logic and adhere to best practices for flash loan implementations, with potential for interface simplification and efficient token handling.
function flashLoan( IERC3156FlashBorrower _receiver, - address _token, uint256 _amount, bytes calldata _data ) external override returns (bool) { - if (_amount > maxFlashLoan(_token)) revert FlashLoanExceedsMaxAmount(); + if (_amount > maxFlashLoan(ibt)) revert FlashLoanExceedsMaxAmount(); - uint256 fee = flashFee(_token, _amount); + uint256 fee = flashFee(ibt, _amount); _updateFees(fee); // Initiate the flash loan by lending the requested IBT amount IERC20(ibt).safeTransfer(address(_receiver), _amount); // Execute the flash loan - if (_receiver.onFlashLoan(msg.sender, _token, _amount, fee, _data) != ON_FLASH_LOAN) + if (_receiver.onFlashLoan(msg.sender, ibt, _amount, fee, _data) != ON_FLASH_LOAN) revert FlashLoanCallbackFailed(); // Repay the debt + fee IERC20(ibt).safeTransferFrom(address(_receiver), address(this), _amount + fee); return true; }
msg.sender
can redeem and withdrawIt can reduce the level of compatiblity and integrity in different situations and with other platforms.
in _beforeRedeem and _beforeWithdraw functions of the PrincipalToken
contract if msg.sender
is not equal to the owner, it reverts.
function _beforeRedeem(uint256 _shares, address _owner) internal nonReentrant whenNotPaused { if (_owner != msg.sender) { revert UnauthorizedCaller(); } ...
VScode
It is recommended that when input address is not the same as msg.sender
check if msg.sender
has alloance from the _owner
address.
#0 - c4-pre-sort
2024-03-03T13:55:42Z
gzeon-c4 marked the issue as sufficient quality report
#1 - c4-judge
2024-03-11T01:33:50Z
JustDravee marked the issue as grade-b