Open sherlock-admin opened 1 year ago
Escalate for 1 USDC
Not a dupe of #190, issue is with the lien array is managed as the payments are made. Fixing #190 wouldn't fix this.
Escalate for 1 USDC
Not a dupe of #190, issue is with the lien array is managed as the payments are made. Fixing #190 wouldn't fix this.
You've created a valid escalation for 1 USDC!
To remove the escalation from consideration: Delete your comment. To change the amount you've staked on this escalation: Edit your comment (do not create a new comment).
You may delete or edit your escalation comment anytime before the 48-hour escalation window closes. After that, the escalation becomes final.
Escalation accepeted
TurnipBoy
medium
_makePayment is logically inconsistent with how lien stack is managed causing payments to multiple liens to fail
Summary
_makePayment(uint256, uint256)
looping logic is inconsistent with how_deleteLienPosition
manages the lien stack._makePayment
loops from 0 toopenLiens.length
but_deleteLienPosition
(called when a lien is fully paid off) actively compresses the lien stack. When a payment pays off multiple liens the compressing effect causes an array OOB error towards the end of the loop.Vulnerability Detail
LienToken.sol#_makePayment(uint256, uint256)
loops from 0 toopenLiens.Length
. This loop attempts to make a payment to each lien calling_payment
with the current index of the loop.LienToken.sol#_deleteLienPosition
is called on liens when they are fully paid off. The most interesting portion of the function is how the lien is removed from the stack. We can see that all liens above the lien in question are slid down the stack and the top is popped. This has the effect of reducing the total length of the array. This is where the logical inconsistency is. If the first lien is paid off, it will be removed and the formerly second lien will now occupy it's index. So then when_payment
is called in the next loop with the next index it won't reference the second lien since the second lien is now in the first lien index.Assuming there are 2 liens on some collateral.
liens[0].amount = 100
andliens[1].amount = 50
. A user wants to pay off their entire lien balance so they call_makePayment(uint256, uint256)
with an amount of 150. On the first loop it calls_payment
with an index of 0. This pays offliens[0]
._deleteLienPosition
is called with index of 0 removingliens[0]
. Because of the sliding logic in_deleteLienPosition
lien[1]
has now slid into thelien[0]
position. On the second loop it calls_payment
with an index of 1. When it tries to grab the data for the lien at that index it will revert due to OOB error because the array no long contains an index of 1.Impact
Large payment are impossible and user must manually pay off each liens separately
Code Snippet
https://github.com/sherlock-audit/2022-10-astaria/blob/main/src/LienToken.sol#L410-L424
Tool used
Manual Review
Recommendation
Payment logic inside of
AuctionHouse.sol
works._makePayment
should be changed to mimic that logic.