@@ -14,11 +14,11 @@ pragma solidity = 0.8.18;
1414// When calling initiate, the necessary tokens for swaps are transferred to
1515// the swap contract. At this point the funds belong to the contract, and
1616// cannot be accessed by anyone else, not even the contract's deployer. The
17- // initiator sets a secret hash, a blocktime the funds will be accessible should
18- // they not be redeemed, and a participant who can redeem before or after the
19- // locktime. The participant can redeem at any time after the initiation
20- // transaction is mined if they have the secret that hashes to the secret hash.
21- // Otherwise, the initiator can refund funds any time after the locktime.
17+ // initiator commits to the swap parameters, including a locktime after which
18+ // the funds will be accessible for refund should they not be redeemed. The
19+ // participant can redeem at any time after the initiation transaction is mined
20+ // if they have the secret that hashes to the secret hash. Otherwise, the
21+ // initiator can refund funds any time after the locktime.
2222//
2323// This contract has no limits on gas used for any transactions.
2424//
@@ -30,7 +30,7 @@ contract ERC20Swap {
3030
3131 address public immutable token_address;
3232
33- // Step is a type that hold's a contract's current step. Empty is the
33+ // Step is a type that hold's a contract's current step. Empty is the
3434 // uninitiated or null value.
3535 enum Step { Empty, Filled, Redeemed, Refunded }
3636
@@ -41,6 +41,7 @@ contract ERC20Swap {
4141 }
4242
4343 bytes32 constant RefundRecord = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ;
44+ bytes32 constant RefundRecordHash = 0xAF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051 ;
4445
4546 // swaps is a map of contract hashes to the "swap record". The swap record
4647 // has the following interpretation.
@@ -134,6 +135,7 @@ contract ERC20Swap {
134135
135136 require (v.value > 0 , "0 val " );
136137 require (v.refundTimestamp > 0 , "0 refundTimestamp " );
138+ require (v.secretHash != RefundRecordHash, "illegal secret hash (refund record hash) " );
137139
138140 bytes32 k = contractKey (v);
139141 bytes32 record = swaps[k];
@@ -153,7 +155,7 @@ contract ERC20Swap {
153155 require (success && (data.length == 0 || abi.decode (data, (bool ))), 'transfer from failed ' );
154156 }
155157
156- // isRedeemable returns whether or not a swap identified by secretHash
158+ // isRedeemable returns whether or not a swap identified by vector
157159 // can be redeemed using secret.
158160 function isRedeemable (Vector calldata v )
159161 public
@@ -165,7 +167,7 @@ contract ERC20Swap {
165167 }
166168
167169 // redeem redeems a Vector. It checks that the sender is not a contract,
168- // and that the secret hash hashes to secretHash. msg.value is tranfered
170+ // and that the secret hashes to secretHash. msg.value is tranfered
169171 // from ETHSwap to the sender.
170172 //
171173 // To prevent reentry attack, it is very important to check the state of the
@@ -223,14 +225,14 @@ contract ERC20Swap {
223225 (bytes32 k , bytes32 record , uint256 blockNum ) = retrieveStatus (v);
224226
225227 // Is this swap initialized?
228+ // This check also guarantees that the swap has not already been
229+ // refunded i.e. record != RefundRecord, since RefundRecord is certainly
230+ // greater than block.number.
226231 require (blockNum > 0 && blockNum <= block .number , "swap not active " );
227232
228233 // Is it already redeemed?
229234 require (! secretValidates (record, v.secretHash), "swap already redeemed " );
230235
231- // Is it already refunded?
232- require (record != RefundRecord, "swap already refunded " );
233-
234236 swaps[k] = RefundRecord;
235237
236238 bool success;
0 commit comments