https://github.com/depayfi/depay-evm-router
🛣 DePay's EVM Web3 Payment Router.
https://github.com/depayfi/depay-evm-router
cryptocurrency evm payments protocol router smart-contracts tokens web3
Last synced: about 2 months ago
JSON representation
🛣 DePay's EVM Web3 Payment Router.
- Host: GitHub
- URL: https://github.com/depayfi/depay-evm-router
- Owner: DePayFi
- License: other
- Created: 2020-10-11T14:38:18.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2025-03-26T16:23:38.000Z (3 months ago)
- Last Synced: 2025-04-06T20:25:34.311Z (3 months ago)
- Topics: cryptocurrency, evm, payments, protocol, router, smart-contracts, tokens, web3
- Language: Solidity
- Homepage: https://depay.com
- Size: 4.72 MB
- Stars: 20
- Watchers: 1
- Forks: 19
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Audit: audits/v1/Audit1.md
Awesome Lists containing this project
README
# DePay's EVM Web3 Payment Router.
## Deployments
Optimization Level: 800,000
### DePayRouterV3
Enables Web3 Payments.
Ethereum:
- [0x365f7B56D2fB16C8Af89D7d33b420E4e013461e8](https://etherscan.io/address/0x365f7B56D2fB16C8Af89D7d33b420E4e013461e8)BNB Smart Chain:
- [0x5F565EDfB9C446976a9F9910631cfeDb6A87220c](https://bscscan.com/address/0x5F565EDfB9C446976a9F9910631cfeDb6A87220c)Polygon (POS):
- [0xe04b08Dfc6CaA0F4Ec523a3Ae283Ece7efE00019](https://polygonscan.com/address/0xe04b08Dfc6CaA0F4Ec523a3Ae283Ece7efE00019)Avalanche:
- [0x39E7C98BF4ac3E4C394dD600397f5f7Ee3779BE8](https://snowtrace.io/address/0x39E7C98BF4ac3E4C394dD600397f5f7Ee3779BE8)Gnosis:
- [0x328FE8bbd30487BB7b5A8eEb909f892E9E229271](https://gnosisscan.io/address/0x328FE8bbd30487BB7b5A8eEb909f892E9E229271)Optimism:
- [0x558302715e3011Be6695605c11A65526D2ba2245](https://optimistic.etherscan.io/address/0x558302715e3011Be6695605c11A65526D2ba2245)Arbitrum:
- [0x328FE8bbd30487BB7b5A8eEb909f892E9E229271](https://arbiscan.io/address/0x328FE8bbd30487BB7b5A8eEb909f892E9E229271)Base:
- [0x48825133EF08327535D0b24d73779E82BE6Ea4d9](https://basescan.org/address/0x48825133EF08327535D0b24d73779E82BE6Ea4d9)Worldchain:
- [0x886eb82a7e5E7310F66A0E83748662A17E391eb0](https://worldscan.org/address/0x886eb82a7e5E7310F66A0E83748662A17E391eb0)### DePayForwarderV3
Allows to pay into smart contracts.
Ethereum:
- [0x61e1b824F97cDe70b73438481ECc8A5Ca380eB87](https://etherscan.io/address/0x61e1b824F97cDe70b73438481ECc8A5Ca380eB87)BNB Smart Chain:
- [0x9D7B9B0F1f8b39d3667C2C8e6A391166F535a477](https://bscscan.com/address/0x9D7B9B0F1f8b39d3667C2C8e6A391166F535a477)Polygon (POS):
- [0xA47D5E0e6684D3ad73F3b94d9DAf18a2f5F97688](https://polygonscan.com/address/0xA47D5E0e6684D3ad73F3b94d9DAf18a2f5F97688)Avalanche:
- [0x376d6B0F8c9b829aAb0a7478952DEF1F8656D7c4](https://snowtrace.io/address/0x376d6B0F8c9b829aAb0a7478952DEF1F8656D7c4)Gnosis:
- [0xd3967a248Bd105CE5511FF5a8136548ADC78E64e](https://gnosisscan.io/address/0xd3967a248Bd105CE5511FF5a8136548ADC78E64e)Optimism:
- [0x2fd0a07a4F73285d0eBa8176426BF9B8c0121206](https://optimistic.etherscan.io/address/0x2fd0a07a4F73285d0eBa8176426BF9B8c0121206)Arbitrum:
- [0xd3967a248Bd105CE5511FF5a8136548ADC78E64e](https://arbiscan.io/address/0xd3967a248Bd105CE5511FF5a8136548ADC78E64e)Base:
- [0xc14318b5D57DB31491dc50295e581a79E56f8A7a](https://basescan.org/address/0xc14318b5D57DB31491dc50295e581a79E56f8A7a)Worldchain:
- [0xFee05C41195985909DDfc9127Db1f94559c46db3](https://worldscan.org/address/0xFee05C41195985909DDfc9127Db1f94559c46db3)### DePayWETHExchangeV1
DePayWETHExchangeV1 allows to swap WETH<>ETH both ways when performing payments using the DePay Router.
Ethereum:
- [0x298f4980525594b3b982779cf74ba76819708D43](https://etherscan.io/address/0x298f4980525594b3b982779cf74ba76819708D43)BNB Smart Chain:
- [0xeEb80d14abfB058AA78DE38813fe705c3e3b243E](https://bscscan.com/address/0xeEb80d14abfB058AA78DE38813fe705c3e3b243E)Polygon (POS):
- [0xaE59C9d3E055BdFAa583E169aA5Ebe395689476a](https://polygonscan.com/address/0xaE59C9d3E055BdFAa583E169aA5Ebe395689476a)Avalanche:
- [0x2d0a6275eaDa0d03226919ce6D93661E589B2d59](https://snowtrace.io/address/0x2d0a6275eaDa0d03226919ce6D93661E589B2d59)Gnosis:
- [0x2d0a6275eaDa0d03226919ce6D93661E589B2d59](https://gnosisscan.io/address/0x2d0a6275eaDa0d03226919ce6D93661E589B2d59)Optimism:
- [0x69594057e2C0224deb1180c7a5Df9ec9d5B611B5](https://optimistic.etherscan.io/address/0x69594057e2C0224deb1180c7a5Df9ec9d5B611B5)Arbitrum:
- [0x7E655088214d0657251A51aDccE9109CFd23B5B5](https://arbiscan.io/address/0x7E655088214d0657251A51aDccE9109CFd23B5B5)Base:
- [0x8206ba765BDD4770B08B807a8819a66A9F035A08](https://basescan.org/address/0x8206ba765BDD4770B08B807a8819a66A9F035A08)Worldchain:
- [0x2CA727BC33915823e3D05fe043d310B8c5b2dC5b](https://worldscan.org/address/0x2CA727BC33915823e3D05fe043d310B8c5b2dC5b)## Functionalities
### pay
The DePay Router smart contract enables decentralized payments with auto-conversion, payment- and protocol-fees.
The main purpose of the DePay Router evolves around the `pay` function.
The DePay Router allows for the following payments:
- NATIVE to NATIVE
- NATIVE to TOKEN
- TOKEN to NATIVE
- TOKEN to WRAPPED
- WRAPPED to NATIVE
- WRAPPED to TOKEN
- NATIVE to WRAPPED
- TOKEN_A to TOKEN_BThe DePay Router offers 3 different `pay` functions which are overloaded and to be differentiated by their method arguments.
The pay funciton of the DePay Router requires a `Payment` struct in order to process a payment. The struct is assembled as follows:
```
struct Payment {
uint256 amountIn;
uint256 paymentAmount;
uint256 feeAmount;
uint256 feeAmount2;
uint256 protocolAmount;
uint256 deadline; // in milliseconds!
address tokenInAddress;
address exchangeAddress;
address tokenOutAddress;
address paymentReceiverAddress;
address feeReceiverAddress;
address feeReceiverAddress2;
uint8 exchangeType;
uint8 receiverType;
bool permit2;
bytes exchangeCallData;
bytes receiverCallData;
}
```#### pay - without any prior approval
Using a blockchains native currency to perform a payment using the DePay Router's `pay` function does not require any upfront approval.
This means payments from:
- NATIVE to NATIVE
- NATIVE to token
- NATIVE to WRAPPEDcan be performed without any prior approval or signature.
```
function pay(
Payment calldata payment
) external payable returns(bool);
``````
pay(
(uint256,uint256,uint256,uint256,uint256,uint256,address,address,address,address,address,address,uint8,uint8,bool,bytes,bytes)
)
``````javascript
router.connect(senderWallet)[
"pay((uint256,uint256,uint256,uint256,uint256,uint256,address,address,address,address,address,address,uint8,uint8,bool,bytes,bytes))"
]({
amountIn: "1000000000",
paymentAmount: "1000000000",
feeAmount: "0",
feeAmount2: "0",
protocolAmount: "0",
deadline: "1727680659852",
tokenInAddress: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
exchangeAddress: "0x0000000000000000000000000000000000000000",
tokenOutAddress: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
paymentReceiverAddress: receiverWallet,
feeReceiverAddress: "0x0000000000000000000000000000000000000000",
feeReceiverAddress2: "0x0000000000000000000000000000000000000000",
exchangeType: 0,
receiverType: 0,
permit2: false,
exchangeCallData: "0x",
receiverCallData: "0x",
}, { value: "1000000000" })
```#### pay - with permit2 SignatureTransfer
The `pay` function in the DePay Router enables token-based payments, which can be enabled by upfront [permit2 SignatureTransfers](https://docs.uniswap.org/contracts/permit2/reference/signature-transfer).
Once the payment sender has allowed the permit2 contract as a spender for a given token and signed a permit2 SignatureTransfer for the DePay Router, the following payments can be performed:
- TOKEN to NATIVE
- TOKEN to WRAPPED
- TOKEN_A to TOKEN_B
- WRAPPED to NATIVE
- WRAPPED to TOKEN```
struct TokenPermissions {
address token;
uint256 amount;
}struct PermitTransferFrom {
TokenPermissions permitted;
uint256 nonce;
uint256 deadline;
}struct PermitTransferFromAndSignature {
IPermit2.PermitTransferFrom permitTransferFrom;
bytes signature;
}function pay(
IDePayRouterV3.Payment calldata payment,
PermitTransferFromAndSignature calldata permitTransferFromAndSignature
) external payable returns(bool);
``````
pay(
(uint256,uint256,uint256,uint256,uint256,uint256,address,address,address,address,address,address,uint8,uint8,bool,bytes,bytes),
(
(
(address,uint256),
uint256,
uint256
),
bytes
)
)
``````javascript
const domain = {
chainId: "10", // e.g. optimism
name: "Permit2",
verifyingContract: permit2Contract.address
}const types = {
PermitTransferFrom: [
{ name: "permitted", type: "TokenPermissions" },
{ name: "spender", type: "address" },
{ name: "nonce", type: "uint256" },
{ name: "deadline", type: "uint256" }
],
TokenPermissions: [
{ name: "token", type: "address" },
{ name: "amount", type: "uint256" },
]
}const data = {
permitted: {
token: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
amount: "100000",
},
spender: routerAddress,
nonce,
deadline
}const signature = await wallets[0]._signTypedData(domain, types, data)
router.connect(senderWallet)[
"pay((uint256,uint256,uint256,uint256,uint256,address,address,address,address,address,uint8,uint8,bool,bytes,bytes),(((address,uint256),uint256,uint256),bytes))"
](
{ // payment
amountIn: "100000",
paymentAmount: "100000",
feeAmount: "0",
feeAmount2: "0",
protocolAmount: "0",
deadline: "1727680659852",
tokenInAddress: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
exchangeAddress: "0x0000000000000000000000000000000000000000",
tokenOutAddress: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
paymentReceiverAddress: receiverWallet,
feeReceiverAddress: "0x0000000000000000000000000000000000000000",
feeReceiverAddress2: "0x0000000000000000000000000000000000000000",
exchangeType: 0,
receiverType: 0,
permit2: true,
exchangeCallData: "0x",
receiverCallData: "0x",
},
{ // PermitTransferFromAndSignature
permitTransferFrom: {
permitted: {
token: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
amount: "100000",
},
nonce,
deadline
},
signature
},
{ value: 0 }
)
```#### pay - with ERC-20 token approval
The `pay` function in the DePay Router enables token-based payments, which can be enabled by upfront [ERC-20 token approvals](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20-approve-address-uint256-).
Once the payment sender has allowed the DePay Router as a spender for a given token, the following payments can be performed:
- TOKEN to NATIVE
- TOKEN to WRAPPED
- TOKEN_A to TOKEN_B
- WRAPPED to NATIVE
- WRAPPED to TOKEN```
function pay(
Payment calldata payment
) external payable returns(bool);
``````
pay(
(uint256,uint256,uint256,uint256,uint256,uint256,address,address,address,address,address,address,uint8,uint8,bool,bytes,bytes)
)
``````javascript
const PAY = "pay((uint256,uint256,uint256,uint256,uint256,uint256,address,address,address,address,address,address,uint8,uint8,bool,bytes,bytes))"router.connect(senderWallet)[PAY]({
amountIn: "100000",
paymentAmount: "100000",
feeAmount: "0",
feeAmount2: "0",
protocolAmount: "0",
deadline: "1727680659852",
tokenInAddress: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
exchangeAddress: "0x0000000000000000000000000000000000000000",
tokenOutAddress: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
paymentReceiverAddress: receiverWallet,
feeReceiverAddress: "0x0000000000000000000000000000000000000000",
feeReceiverAddress2: "0x0000000000000000000000000000000000000000",
exchangeType: 0,
receiverType: 0,
permit2: false,
exchangeCallData: "0x",
receiverCallData: "0x",
}, { value: 0 })
```### Payment Event
The `DePayRouterV3` emits a `Payment` event for all payments:
```
event Payment(
address indexed from,
address indexed to,
uint256 indexed deadline,
uint256 amountIn,
uint256 paymentAmount,
uint256 feeAmount,
uint256 feeAmount2,
uint256 protocolAmount,
uint256 slippageAmount,
address tokenInAddress,
address tokenOutAddress,
address feeReceiverAddress,
address feeReceiverAddress2,
);
```## Development
Create an `.env` file with the following content:
```
NODE_ENV=developmentMNEMONIC="shine romance erase resource daring bean talk right cupboard visa renew galaxy"
#(0) 0xdde3dc4308A7856D49D1d7303bB630Bccb45Caf9
#(1) 0x26Fe22F655303151C2ef3b2D097F842ab27Ef940
#(2) 0x877a79C20028F9ef81e956B43B917703cC22A07A
#(3) 0x3a36b51c5125A9c064f4Cd2F492989618CF7660EARBITRUM_NOVA_RPC_URL=https://arbitrum-nova.blastapi.io/
ARBITRUM_ONE_RPC_URL=https://arbitrum-one.blastapi.io/
AVALANCHE_RPC_URL=https://ava-mainnet.blastapi.io//ext/bc/C/rpc
BSC_RPC_URL=https://bsc-mainnet.blastapi.io/
ETHEREUM_RPC_URL=https://eth-mainnet.blastapi.io/
GNOSIS_RPC_URL=https://gnosis-mainnet.blastapi.io/
OPTIMISM_RPC_URL=https://optimism.blockpi.network/v1/rpc/public
POLYGON_RPC_URL=https://polygon-mainnet.blastapi.io/
POLYGON_ZKEVM_RPC_URL=https://polygon-zkevm-mainnet.blastapi.io/
ZKSYNC_ERA_RPC_URL=https://mainnet.era.zksync.io
```### Quick Start
```
yarn install
yarn test
```### Testing
Test on a specific chain:
```
yarn test:
```e.g. `ethereum`, `bsc` etc.
Test on all blockchains:
```
yarn test
```Test single files:
```
npx hardhat test test/optimism/pay_with_exchange_conversion.spec.ts --config hardhat.config.optimism.ts
```### Deploy
1. `yarn flatten`
2. Deploy flatten contract