Skip to content

Commit

Permalink
fix: stop buyer from griefing cancellation by reflecting reimbursemen…
Browse files Browse the repository at this point in the history
…t (Finding 12) (#41)

* test: demonstrate griefing if buyer reflects reimbursement

* fix: always escrow native-token reimbursement

* perf: use variable instead of repeated `address(this).balance`
  • Loading branch information
ARR4N authored Aug 11, 2024
1 parent 4cf3121 commit 3121bf4
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 10 deletions.
1 change: 1 addition & 0 deletions cache/fuzz/failures
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ cc 62cb2547a6172f5d0617d65ba83b530caa08f54d480f5133be3ed8b00e5fe294 # shrinks to
cc 9fbb337e2328ae5b966a1318433dae1046ac9b4c62058b7ea0534eeef325f555 # shrinks to 0xc7827d300000000000000000000000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f00000000000000000000000000000000000000000000000000000000000003190000000000000000000000000000000000000000000000000000000000001e7d00000000000000000000000000000000000000000000000000000000000020ba000000000000000000000000000000000000000000000000000000000000226b0000000000000000000000001f95d37f27ea0dea9c252fc09d5a6eaa97647353000000000000000000000000000000000000000000000000000000000000177e0000000000000000000000000000000000000000000000000000000000000c1b00000000000000000000000000000000000000000000000000000000000002bf0000000000000000000000000000000000000000000000000000000000002150000000000000000000000000000000000000000000000000000000000000017e00000000000000000000000000000000000000000000000000000000000021f9000000000000000000000000000000000000000000000000000000000000002500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000100c000000000000000000000000000000000000000000000000000000000000226b00000000000000000000000000000000000000000000000000000000000002150000000000000000000000000000000000000000000000000000000000002119000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000bf500000000000000000000000000000000000000000000000000000000000002850000000000000000000000000000000000000000000000000000000000001473000000000000000000000000000000000000000000000000000000000000208b000000000000000000000000000000000000000000000000000000000000151900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000137a0000000000000000000000000000000000000000000000000000000000000214000000000000000000000000000000000000000000000000000000000000157f00000000000000000000000000000000000000000000000000000000000022bb00000000000000000000000000000000000000000000000000000000000002ea00000000000000000000000000000000000000000000000000000000000002630000000000000000000000000000000000000000000000000000000000000b230000000000000000000000000000000000000000000000000000000000000ddf0000000000000000000000000000000000000000000000000000000000001616000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c70000000000000000000000000000000000000000000000000000000000001411000000000000000000000000000000000000000000000000000000000000120d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014730000000000000000000000000000000000000000000000000000000000000fb700000000000000000000000000000000000000000000000000000000000000670000000000000000000000000000000000000000000000000000000000001b2b0000000000000000000000000000000000000000000000000000000000000741000000000000000000000000000000000000000000000000000000000000057400000000000000000000006572696e67a164736f6c6343000819000a0000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000069a0000000000000000000000000000000000000000000000000000000000000c9400000000000000000000000000000000000000000000000000000000000004ef000000000000000000000000000000000000000000000000000000000000218700000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000001665000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000137b000000000000000000000000000000000000000000000000000000000000078600000000000000000000000000000000000000000000000000000000fffffffe000000000000000000000000000000000000000000000000000000000000034900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020500000000000000000000000000000000000000000000000000000000000001ba0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000074d000000000000000000000000000000000000000000000000000000000000195300000000000000000000000000000000000000000000000000000000000001750000000000000000000000000000000000000000000000000000000000000a5b0000000000000000000000000000000000000000000000000000000000001f8f00000000000000000000000000000000000000000000000000000000000010e700000000000000000000000000000000000000000000000000000000000007de0000000000000000000000000000000000000000000000000000000000000c920000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000075636365656473207768656e206e6f206c6f6e68000000000000000000000000000000000000000000000000000000000000feff0000000000000000000000000000000000000000000000000000000000000b25000000000000000000000000000000000000000000000000000000000000022f0000000000000000000000000000000000000000000000000000000000000ba20000000000000000000000000000000000000000000000000000000000000e8400000000000000000000000000000000000000000000000000000000000011c00000000000000000000000000000000000000000000000000000000000000fbd00000000000000000000000000000000000000000000000000000000000011260000000000000000000000000000000000000000000000000000000000002372000000000000000000000000000000000000000000000000000000000000142500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000185900000000000000000000000000000000000000000000000000000000000016d30000000000000000000000000000000000000000000000000000000000001e5300616c616e63652061667465722073696e676c65206465706f7369740000000100304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50000000000000000000000000000000000000000000000000000000000618f5880000000000000000000000000000000000000000000000000000000000001bea0000000000000000000000000000000000000000000000000000000000000158000000000000000000000000000000000000000000000000000000000000128300000000000000000000000000000000000000000000000000000000000015300000000000000000000000000000000000000000000000000000000000001202000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c160000000000000000000000000000000000000000000000000000000000000286000000000000000000000000000000000000000000000000000019985a5b195800000000000000000000000000000000000000000000000000000000000021e80000000000000000000000000000000000000000000000000000000000001f1b0000000000000000000000000000000000000000000000000000000000001e5400000000000000000000000000000000000000000000000000000000000007880072726f723a2061203d3d2062206e6f7420736174697366696564205b75696f000000000000000000000000000000000000000000000000000000003ccfd60a000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000012bd0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000012bc0000000000000000000000000000000000000000000000000000000000000f860000000000000000000000000000000000000000000000000000000000000c1700304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f5000000000000000000000000000000000000000000000000000000000000019360000000000000000000000000000000000000000000000000000000000000d82000000000000000000000000000000000000000000000000000000000000212f0000000000000000000000000000000000000000000000000000000000001f8e00000000000000000000000000000000000000000000000000000000000005720000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000158100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001
cc eba7b1846d961e53cbfdc530b6ab276e16f2e2387ae18928c7803be23d09e595 # shrinks to 0xc6bda13300000000000000000000000055b48610427159610b017e6da32aad3e8ff3d9e500000000000000000000000000000000000000000000000000000000000008ca0000000000000000000000000000000000000000000000000000000000003bf9000000000000000000000000000000000000000000000000000000000000038b0000000000000000000000000000000000000000000000000000000000005cef00000000000000000000000000000000000000000000000000000000000005ac0000000000000000000000000000000000000000000000000000000000000591000000000000000000000000000000000000000000000000000000000000065d0000000000000000000000000000000000000000000000000000000000003a2f000000000000000000000000000000000000000000000000000000000000094f00000000000000000000000000000000000000000000000000000000000001ab0000000000000000000000000000000000000000000000000000000000004f5d000000000000000000000000000000000000000000000000000000000000779f0000000000000000000000000000000000000000000000000000000000000be800000000000000000000000000000000000000000000000000000000000011c2000000000000000000000000000000000000000000000000000000000000540300000000000000000000000000000000000000000000000000000000000028bc000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000003de00000000000000000000000000000000000000000000000000000000000005270000000000000000000000000000000000000000000000000000000000002d33000000000000000000000000000000000000000000000000000000000000532b00000000000000000000000000000000000000000000000000000000000033c70000000000000000000000000000000000000000000000000000000000000b8b0000000000000000000000000000000000000000000000000000000000000fd700000000000000000000000000000000000000000000000000000000000000b3
cc 2d8d503a4c6a845b2da1d9a716d23aa581fa1db68e8e9bc87a5eed8dc0591f2d # shrinks to 0xc6bda1330000000000000000000000004342f35a708465557852b4e6094b8755eed5cb0f0000000000000000000000000b3916c65a02e0dd862268e094955e35e8a009d000000000000000000000000034bdc0692b937f7196854c997a5e46cefa7f0136000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001768b9cb337e3f520e77b8160650d100000000000000000000000074d3a17d89e233cceda8c7f00aaf47717b363512000000000000000000000000000000000000000000000000007aa59387f6bc9b0000000000000000000000009193c2261ef4826549e39e20f5bad0d22d99110a00014c402636fd861c8750828eabee0874da64ce5cb73456dc71afd8419ce636000000000000000000000000b00980db33e480d7758fa43f599fc21ec8937c4e00000000000000000000000000000000002235c3e8c9f93a4798848e504559d00000000000000000000000008acaa514e8e7e8a87e666e8b889327099fb83514000000000000000000000000000000001fff6defaf837ed75540121dc284394600000000000000000000000024eefe4dff0b6b95cd5f39dc97bb683151785df4000000000000000001c63a3c4a5e02e872b83cd3de8a2228dff9e7a1022ff8a30000000000000000000000000000000000dccbc59f5389ad1b931be7c493be69000000000000000000000000000000000000000000000000191fcfcd50099fbc0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000eeb23b665d595bbfdebf9a946bf24c84ac1521a9d5b082201998f2d340b0e153040411785def31143190a6a4baea151b70ba045900000000000000000000000000000000000000000000000000000b2eb792712f0000000000000000000000000000000016d89e07054450c152a47e5e17250462000000000000000000000000000000000000000000000000000000000032ad5f0000000000000fad752dbae94f752720a8384dc6c4f526e11a64d0c41ab932ec000000000000000000000000000000000000000000000000000000000000003200000000000000000000000094dfc714f544acb8c7c58b591bc56d5dbfaf54cc
cc eb43b982e663eb1fa05b2c876facadc58cf2e6217aa72d46ab9abe3f682c37fa # shrinks to 0xef7b7b9c0000000000000000000000007bf881c2cdde0140505ebe78ca1153e6457977ed0000000000000000000000001575f21ee7eca3018c90d8938ddf1f4cb1256dce000000000000000000000000ee22a7749ac0d670fc531b444def7371c49f3163000000000000000000000000000000000000000000000000000000000000000e0000000000000008e2a998e993ed40b343954f3af9f8a6d0d4da9df0929f05b600000000000000000000000079c15a682600c0325163926fae9d787cf9bc7c4b00000000000000000000000000000be18219cb3614f66a7965ca1c96fed4e923000000000000000000000000cfb8d69f87cad32987e13a4bc1e6098d8ff0dffe3e8f10c0df6f0441023a585a783118ce5c59556083d446b0b832fcc4e803fe110000000000000000000000003b41009990dc966ddf1d3badc30dd1151d6523fb00000000000000000000000000000000000269515deb6005ac821c1c0ffb1eae000000000000000000000000188f0be7110242f7725ede0e3d63553bc52bbba400000000000000000000000000000000000000000000000000000000005f13710000000000000000000000007c6e3303497d8931e4f7ce7e509286636308daee00000000000000000000000000000000000000000000000000065d8bee5b95fa0000000000000000000000000000000000000000000000000000000000000d4f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000031c44567ba45b008173ab74c855472cfcee2e768fb890c705dd2e1fc2fd3ba34f48f0abd7d16b2e9c8723827e7456a0ad01199d800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001fec00000000000000000000000000000000000037b59a924edc548044a1329c43a900000000000000000000000000000000000000000035aa0d3aea8fb12e13cf0a00000000000000000000000000001776f623f70b209db0a66cbe6272833ee1a20000000000000000000000000000000000000000000000026bef7177341a76a400000000000000000000000030ec50a235b3e12d069be6914048dfbbc0367c740000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
12 changes: 3 additions & 9 deletions src/ConsiderationLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,10 @@ library ConsiderationLib {
*/
function _cancel(Consideration memory, PayableParties memory parties, IEscrow escrow) internal {
// MUST remain as the last step for the same reason as _disburseFunds().
_sendOrEscrow(parties.buyer, address(this).balance, escrow);
}

function _sendOrEscrow(address payable to, uint256 amount, IEscrow escrow) internal {
// 20k for a fresh SSTORE and an arbitrary 10k overhead
(bool success,) = to.call{value: amount, gas: 30_000}("");
if (success) {
return;
uint256 bal = address(this).balance;
if (bal > 0) {
escrow.deposit{value: bal}(parties.buyer);
}
escrow.deposit{value: amount}(to);
}

/// @dev Returns whether the contract's remaining balance is zero.
Expand Down
26 changes: 25 additions & 1 deletion test/ERC721ForXTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -293,10 +293,18 @@ abstract contract ERC721ForXTest is SwapperTestBase {
{
uint256 expectedBuyerBalance = _balance(test.buyer()) + _balance(swapper);

if (!_isERC20Test() && _balance(swapper) > 0) {
vm.expectEmit(true, true, true, true, address(factory.escrow()));
emit Deposit(test.buyer(), _balance(swapper));
}
vm.expectEmit(true, true, true, true, address(factory));
emit Cancelled(_swapper(t));
_cancelAs(t, asSeller ? test.seller() : test.buyer());

if (factory.escrow().balance(test.buyer()) > 0) {
factory.escrow().withdraw(test.buyer());
}

assertEq(_balance(swapper), 0, "swapper balance zero after cancel");
assertEq(_balance(test.buyer()), expectedBuyerBalance, "buyer balance after cancel");

Expand Down Expand Up @@ -368,7 +376,7 @@ abstract contract ERC721ForXTest is SwapperTestBase {
);
}

function testGriefNativeTokenInvariant(ERC721TestCase memory t, uint8 vandalIndex)
function testGriefNativeTokenInvariantOnFill(ERC721TestCase memory t, uint8 vandalIndex)
external
assumeValidTest(t.base, Assumptions({sufficientPayment: true, validPlatformFee: true, approving: true}))
{
Expand Down Expand Up @@ -397,6 +405,22 @@ abstract contract ERC721ForXTest is SwapperTestBase {
);
}

function testGriefNativeTokenInvariantOnCancel(ERC721TestCase memory t)
external
assumeValidTest(t.base, Assumptions({sufficientPayment: true, validPlatformFee: true, approving: true}))
{
vm.skip(_isERC20Test());

// If the buyer sends any funds back during cancellation, the post-execution invariant of zero balance will be
// broken.
t.base.parties.buyer = address(new FundsReflector());
address swapper = _beforeExecute(t);

vm.expectEmit(true, true, true, true, address(factory));
emit Cancelled(swapper);
_cancelAs(t, t.base.seller());
}

/**
* @dev The generated `<T>ForERC20Deployer` contracts have payable `fill()` functions because of simple identifier
* replacement. Being payable is unnecessary and could (but doesn't) risk accidental locking of funds. There are two
Expand Down

0 comments on commit 3121bf4

Please sign in to comment.