40,000 USDC
View results
Submission Details
Severity: medium

`Price` might be less than final audit price when buyer sends more token to escrow to increase reward.

Summary

In the current implementation price is never changed once set.

In case buyer sent more token to increase escrow pot size, then price should be updated to contract's token balance so that price would be final price not initial price.

Vulnerability Details

function confirmReceipt() external onlyBuyer inState(State.Created) {
s_state = State.Confirmed;
emit Confirmed(i_seller);
i_tokenContract.safeTransfer(i_seller, i_tokenContract.balanceOf(address(this))); //@audit - should be price
}
function resolveDispute(uint256 buyerAward) external onlyArbiter nonReentrant inState(State.Disputed) {
uint256 tokenBalance = i_tokenContract.balanceOf(address(this));
uint256 totalFee = buyerAward + i_arbiterFee; // Reverts on overflow
if (totalFee > tokenBalance) {
revert Escrow__TotalFeeExceedsBalance(tokenBalance, totalFee);
}
s_state = State.Resolved;
emit Resolved(i_buyer, i_seller);
if (buyerAward > 0) {
i_tokenContract.safeTransfer(i_buyer, buyerAward);
}
if (i_arbiterFee > 0) {
i_tokenContract.safeTransfer(i_arbiter, i_arbiterFee);
}
tokenBalance = i_tokenContract.balanceOf(address(this)); //@audit - price - totalFee
if (tokenBalance > 0) {
i_tokenContract.safeTransfer(i_seller, tokenBalance);
}

Impact

Price might not less than final price of audit.

Tools Used

Manual Review

Recommendations

As there's no way to hook transfer event, price should be updated to balanceOf(address(this)) at confirmReceipt(), and resolveDispute()

- uint256 private immutable i_price;
+ uint256 private i_price;
function confirmReceipt() external onlyBuyer inState(State.Created) {
s_state = State.Confirmed;
emit Confirmed(i_seller);
- i_tokenContract.safeTransfer(i_seller, i_tokenContract.balanceOf(address(this)));
+ price = i_tokenContract.balanceOf(address(this));
+ i_tokenContract.safeTransfer(i_seller, price); //@audit - should be price
}
function resolveDispute(uint256 buyerAward) external onlyArbiter nonReentrant inState(State.Disputed) {
uint256 tokenBalance = i_tokenContract.balanceOf(address(this));
uint256 totalFee = buyerAward + i_arbiterFee; // Reverts on overflow
if (totalFee > tokenBalance) {
revert Escrow__TotalFeeExceedsBalance(tokenBalance, totalFee);
}
s_state = State.Resolved;
emit Resolved(i_buyer, i_seller);
if (buyerAward > 0) {
i_tokenContract.safeTransfer(i_buyer, buyerAward);
}
if (i_arbiterFee > 0) {
i_tokenContract.safeTransfer(i_arbiter, i_arbiterFee);
}
- tokenBalance = i_tokenContract.balanceOf(address(this)); //@audit - price - totalFee
+ price = i_tokenContract.balanceOf(address(this));
+ tokenBalance = price - totalFee;
if (tokenBalance > 0) {
i_tokenContract.safeTransfer(i_seller, tokenBalance);
}

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.