Platform: Code4rena
Start Date: 05/01/2023
Pot Size: $90,500 USDC
Total HM: 55
Participants: 103
Period: 14 days
Judge: Picodes
Total Solo HM: 18
Id: 202
League: ETH
Rank: 38/103
Findings: 3
Award: $291.64
🌟 Selected for report: 1
🚀 Solo Findings: 0
229.5167 USDC - $229.52
https://github.com/code-423n4/2023-01-astaria/blob/main/src/LienToken.sol#L646
In _paymentAH
function from LienToken.sol, the stack
argument should be storage instead of memory. This bug was also disclosed in the Spearbit audit of this program and was resolved during here: https://github.com/AstariaXYZ/astaria-core/pull/201/commits/5a0a86837c0dcf2f6768e8a42aa4215666b57f11, but was later re-introduced https://github.com/AstariaXYZ/astaria-core/commit/be9a14d08caafe125c44f6876ebb4f28f06d83d4 here. Marking it as high-severity as it was marked as same in the audit.
function _paymentAH( LienStorage storage s, address token, AuctionStack[] memory stack, uint256 position, uint256 payment, address payer ) internal returns (uint256) { uint256 lienId = stack[position].lienId; uint256 end = stack[position].end; uint256 owing = stack[position].amountOwed; //...[deleted lines to show bug] delete s.lienMeta[lienId]; //full delete delete stack[position]; // <- no effect on storage }
The position here is not deleted after the debt is paid as it is a memory pointer.
The first fix can be used again and it would work.
#0 - androolloyd
2023-01-25T17:33:29Z
so digging into this more since this payment flow is designed to run only once, and the state is stored inside the clearing house not the lien token, im not sure this matters, the deletion of the auction stack should be handled seperately inside the clearing house for the deposit.
#1 - c4-judge
2023-01-26T17:52:26Z
Picodes marked the issue as primary issue
#2 - c4-sponsor
2023-01-27T03:24:29Z
SantiagoGregory marked the issue as sponsor acknowledged
#3 - c4-judge
2023-02-18T16:34:39Z
Picodes marked the issue as selected for report
#4 - Picodes
2023-02-18T16:38:02Z
The description of the impact of the finding is very brief for this issue and its duplicates.
@androolloyd the auction stack is in ClearingHouse
, but the issue still stands as it is not deleted in ClearingHouse
although it should be, right?
#5 - c4-judge
2023-02-18T16:38:19Z
Picodes marked the issue as satisfactory
#6 - c4-judge
2023-02-18T16:38:42Z
Picodes marked the issue as partial-50
#7 - c4-judge
2023-02-18T16:39:05Z
Picodes marked the issue as full credit
#8 - c4-judge
2023-02-18T16:39:13Z
Picodes changed the severity to 2 (Med Risk)
#9 - androolloyd
2023-02-23T16:47:39Z
The description of the impact of the finding is very brief for this issue and its duplicates.
@androolloyd the auction stack is in
ClearingHouse
, but the issue still stands as it is not deleted inClearingHouse
although it should be, right?
yes it should be.
#10 - c4-judge
2023-02-23T18:50:01Z
Picodes marked the issue as satisfactory
🌟 Selected for report: ladboy233
Also found by: Bjorn_bug, Jujic, KIntern_NA, RaymondFam, fs0c, joestakey, kaden, obront, unforgiven
25.3332 USDC - $25.33
https://github.com/code-423n4/2023-01-astaria/blob/main/src/LienToken.sol#L643
The actual transfer might be less that the amount transfered. This would lead to wrong accounting in the contract.
Eg: In _paymentAH
function, if the token
is a fee-on-transfer token then the actual tokens transferred from payer
to payee
would be less than payment
, but the payee should receive the full amount.
if (payment > 0) s.TRANSFER_PROXY.tokenTransferFrom(token, payer, payee, payment);
Transfer the tokens first and compare pre-/after token balances to compute the actual deposited amount.
#0 - c4-judge
2023-01-23T12:10:03Z
Picodes marked the issue as duplicate of #51
#1 - c4-judge
2023-02-23T11:51:01Z
Picodes marked the issue as satisfactory
🌟 Selected for report: c3phas
Also found by: 0x1f8b, 0xAgro, 0xSmartContract, 0xackermann, 0xkato, Aymen0909, Bnke0x0, CloudX, IllIllI, PaludoX0, Rageur, Rahoz, RaymondFam, ReyAdmirado, Rolezn, SadBase, SaeedAlipoor01988, caventa, chaduke, chrisdior4, fatherOfBlocks, fs0c, kaden, nogo, pfapostol, shark, synackrst
36.79 USDC - $36.79
When a loan is sold on Seapost and _payDebt
is called, it loops thought the auction stack and calls _paymentAH
for each, decrementing the remaining payment as money is spent.
This loop can be ended when payment == 0.
uint256 i; for (; i < stack.length;) { + if (payment == 0) break; uint256 spent; unchecked { spent = _paymentAH(s, token, stack, i, payment, payer);
LientToken.sol:_paymentAH
can be removed as it is not used.uint256 end = stack[position].end;
CollateralToken.sol:releaseToAddress
can be removed as it is not usedaddress tokenContract = underlying.tokenContract;
CollateralToken.sol:liquidatorNFTClaim
address tokenContract = underlying.tokenContract; uint256 tokenId = underlying.tokenId;
Both tokenContract and tokenId are unused.
In PublicVault.sol
function _totalAssets(VaultData storage s) internal view returns (uint256) { uint256 delta_t = block.timestamp - s.last; return uint256(s.slope).mulDivDown(delta_t, 1) + uint256(s.yIntercept); }
uint256(s.slope).mulDivDown(delta_t, 1)
can be change to uint256(s.slope)*delta_t
to save gas.
#0 - c4-judge
2023-02-24T10:26:00Z
Picodes marked the issue as grade-b