Skip to content

Commit 1c5644e

Browse files
committed
remove completeTokenPurchase
1 parent 5071642 commit 1c5644e

File tree

4 files changed

+3
-136
lines changed

4 files changed

+3
-136
lines changed

README.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,14 @@ This is a forwarder contract that forwards the swap providers transaction (LiFi,
77
- Data Logging - this is essential for attribution and linking on-chain and off-chain data
88
- Fee Splitting - this allows us to split the fees in-flight and flexibility to change fees on a per client basis
99
- Data validation - this provides high-security as only thirdweb originated swaps with untampered data can use this contract
10-
- exit point for contract calls - for LiFi, they can only guarantee toAmount for contract calls. This allows use to add a contract call to transferEnd that forwards the end funds to the user
1110
- Stateless - this will be deployed on many different chains. We don’t want to have to call addClient, changeFee, addSwapProvider, etc on every single chain for every change. Therefore, this should not rely on data held in the state of the contract, but rather data passed in
1211

1312
[PayGateway Reference](img/gateway.png)
1413

15-
[PayGateway With Transfer End](img/gateway-transfer-end.png)
16-
1714
## Features
1815

1916
- Event Logging
2017
- TokenPurchaseInitiated logs the necessary events attribution and link off-chain and on-chain through clientId and transactionId. We use bytes32 instead of string for clientId and transactionId (uuid in database) because this allows recovering indexed pre-image
21-
- TokenPurchaseCompleted logs the transfer end in case of a contract call and can be used for indexing bridge transactions by just listening to our Thirdweb PayGateway deployments
2218
- FeePayout logs the fees distributed among the payees
2319
- Fee Splitting
2420
- supports many parties for fee payouts (we only expect us and client). It also allows for flexible fees on a per client basis

img/gateway-transfer-end.png

-267 KB
Binary file not shown.

src/PayGatewayModule.sol

Lines changed: 3 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,6 @@ contract PayGatewayModule is EIP712, ModularModule, ReentrancyGuard {
9595
uint256 tokenAmount
9696
);
9797

98-
event TokenPurchaseCompleted(
99-
bytes32 indexed clientId,
100-
address indexed receiver,
101-
bytes32 transactionId,
102-
address tokenAddress,
103-
uint256 tokenAmount
104-
);
105-
10698
event FeePayout(
10799
bytes32 indexed clientId,
108100
address indexed sender,
@@ -128,7 +120,7 @@ contract PayGatewayModule is EIP712, ModularModule, ReentrancyGuard {
128120

129121
/// @notice Returns all implemented callback and fallback functions.
130122
function getModuleConfig() external pure override returns (ModuleConfig memory config) {
131-
config.fallbackFunctions = new FallbackFunction[](6);
123+
config.fallbackFunctions = new FallbackFunction[](5);
132124

133125
config.fallbackFunctions[0] = FallbackFunction({
134126
selector: this.withdrawTo.selector,
@@ -142,12 +134,8 @@ contract PayGatewayModule is EIP712, ModularModule, ReentrancyGuard {
142134
selector: this.initiateTokenPurchase.selector,
143135
permissionBits: 0
144136
});
145-
config.fallbackFunctions[3] = FallbackFunction({
146-
selector: this.completeTokenPurchase.selector,
147-
permissionBits: 0
148-
});
149-
config.fallbackFunctions[4] = FallbackFunction({ selector: this.eip712Domain.selector, permissionBits: 0 });
150-
config.fallbackFunctions[5] = FallbackFunction({ selector: this.isProcessed.selector, permissionBits: 0 });
137+
config.fallbackFunctions[3] = FallbackFunction({ selector: this.eip712Domain.selector, permissionBits: 0 });
138+
config.fallbackFunctions[4] = FallbackFunction({ selector: this.isProcessed.selector, permissionBits: 0 });
151139
}
152140

153141
/*///////////////////////////////////////////////////////////////
@@ -264,48 +252,6 @@ contract PayGatewayModule is EIP712, ModularModule, ReentrancyGuard {
264252
emit TokenPurchaseInitiated(req.clientId, msg.sender, req.transactionId, req.tokenAddress, req.tokenAmount);
265253
}
266254

267-
/**
268-
@notice
269-
The purpose of completeTokenPurchase is to provide a forwarding contract call
270-
on the destination chain. For some swap providers, they can only guarantee the toAmount
271-
if we use a contract call. This allows us to call the endTransfer function and forward the
272-
funds to the end user.
273-
274-
Requirements:
275-
1. Log the transfer end
276-
2. forward the user funds
277-
*/
278-
function completeTokenPurchase(
279-
bytes32 clientId,
280-
bytes32 transactionId,
281-
address tokenAddress,
282-
uint256 tokenAmount,
283-
address payable receiverAddress
284-
) external payable nonReentrant {
285-
if (tokenAmount == 0) {
286-
revert PayGatewayInvalidAmount(tokenAmount);
287-
}
288-
289-
if (_isTokenNative(tokenAddress)) {
290-
if (msg.value != tokenAmount) {
291-
revert PayGatewayMismatchedValue(tokenAmount, msg.value);
292-
}
293-
}
294-
295-
// pull user funds
296-
if (_isTokenERC20(tokenAddress)) {
297-
if (msg.value != 0) {
298-
revert PayGatewayMsgValueNotZero();
299-
}
300-
301-
SafeTransferLib.safeTransferFrom(tokenAddress, msg.sender, receiverAddress, tokenAmount);
302-
} else {
303-
SafeTransferLib.safeTransferETH(receiverAddress, tokenAmount);
304-
}
305-
306-
emit TokenPurchaseCompleted(clientId, receiverAddress, transactionId, tokenAddress, tokenAmount);
307-
}
308-
309255
/*///////////////////////////////////////////////////////////////
310256
Internal functions
311257
//////////////////////////////////////////////////////////////*/

test/PayGateway.t.sol

Lines changed: 0 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,6 @@ contract PayGatewayTest is Test {
2020
uint256 tokenAmount
2121
);
2222

23-
event TokenPurchaseCompleted(
24-
bytes32 indexed clientId,
25-
address indexed receiver,
26-
bytes32 transactionId,
27-
address tokenAddress,
28-
uint256 tokenAmount
29-
);
30-
3123
event FeePayout(
3224
bytes32 indexed clientId,
3325
address indexed sender,
@@ -467,71 +459,4 @@ contract PayGatewayTest is Test {
467459
);
468460
gateway.initiateTokenPurchase(req, _signature);
469461
}
470-
471-
// /*///////////////////////////////////////////////////////////////
472-
// Test `completeTokenPurchase`
473-
// //////////////////////////////////////////////////////////////*/
474-
475-
function test_completeTokenPurchase_erc20() public {
476-
uint256 sendValue = 1 ether;
477-
478-
// approve amount to gateway contract
479-
vm.prank(sender);
480-
mockERC20.approve(address(gateway), sendValue);
481-
482-
// state/balances before sending transaction
483-
uint256 ownerBalanceBefore = mockERC20.balanceOf(owner);
484-
uint256 senderBalanceBefore = mockERC20.balanceOf(sender);
485-
uint256 receiverBalanceBefore = mockERC20.balanceOf(receiver);
486-
487-
// send transaction
488-
bytes32 _transactionId = keccak256("transaction ID");
489-
vm.prank(sender);
490-
gateway.completeTokenPurchase(clientId, _transactionId, address(mockERC20), sendValue, receiver);
491-
492-
// check balances after transaction
493-
assertEq(mockERC20.balanceOf(owner), ownerBalanceBefore);
494-
assertEq(mockERC20.balanceOf(sender), senderBalanceBefore - sendValue);
495-
assertEq(mockERC20.balanceOf(receiver), receiverBalanceBefore + sendValue);
496-
}
497-
498-
function test_completeTokenPurchase_nativeToken() public {
499-
uint256 sendValue = 1 ether;
500-
501-
// state/balances before sending transaction
502-
uint256 ownerBalanceBefore = owner.balance;
503-
uint256 senderBalanceBefore = sender.balance;
504-
uint256 receiverBalanceBefore = receiver.balance;
505-
506-
// send transaction
507-
bytes32 _transactionId = keccak256("transaction ID");
508-
vm.prank(sender);
509-
gateway.completeTokenPurchase{ value: sendValue }(
510-
clientId,
511-
_transactionId,
512-
address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE),
513-
sendValue,
514-
receiver
515-
);
516-
517-
// check balances after transaction
518-
assertEq(owner.balance, ownerBalanceBefore);
519-
assertEq(sender.balance, senderBalanceBefore - sendValue);
520-
assertEq(receiver.balance, receiverBalanceBefore + sendValue);
521-
}
522-
523-
function test_completeTokenPurchase_events() public {
524-
uint256 sendValue = 1 ether;
525-
526-
// approve amount to gateway contract
527-
vm.prank(sender);
528-
mockERC20.approve(address(gateway), sendValue);
529-
530-
// send transaction
531-
bytes32 _transactionId = keccak256("transaction ID");
532-
vm.prank(sender);
533-
vm.expectEmit(true, true, false, true);
534-
emit TokenPurchaseCompleted(clientId, receiver, _transactionId, address(mockERC20), sendValue);
535-
gateway.completeTokenPurchase(clientId, _transactionId, address(mockERC20), sendValue, receiver);
536-
}
537462
}

0 commit comments

Comments
 (0)