Skip to content

Commit

Permalink
add all contract exchange variations and enable bsc for testing
Browse files Browse the repository at this point in the history
  • Loading branch information
10xSebastian committed Aug 9, 2023
1 parent 317721a commit 1ab9fce
Show file tree
Hide file tree
Showing 15 changed files with 312 additions and 117 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ yarn test
Test single files:

```
npx hardhat test test/ethereum/pay_with_exchange_conversion.spec.ts --config hardhat.config.ethereum.ts
npx hardhat test test/bsc/pay_with_exchange_conversion.spec.ts --config hardhat.config.bsc.ts
```

### Deploy
Expand Down
41 changes: 41 additions & 0 deletions contracts/DePayForwarderV2.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// SPDX-License-Identifier: BUSL-1.1

pragma solidity >=0.8.18 <0.9.0;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "hardhat/console.sol";

contract DePayForwarderV2 is Ownable {

using SafeERC20 for IERC20;

// Address representing the NATIVE token (e.g. ETH, BNB, MATIC, etc.)
address public constant NATIVE = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

constructor () {}

// Accepts NATIVE payments, which is required in order to forward native payments
receive() external payable {}

function forward(
uint256 amount,
address token,
uint8 forwardingType,
address receiver,
bytes calldata callData
) external payable returns(bool){

bool success;
if(forwardingType == 1) { // pull
IERC20(token).safeApprove(receiver, amount);
// (success,) = receiver.delegateCall(callData);
} else if(forwardingType == 2) { // push
IERC20(token).safeTransfer(receiver, amount);
(success,) = receiver.call(callData);
}
require(success, "DePay: forwarding payment to receiver failed!");

return true;
}
}
16 changes: 8 additions & 8 deletions contracts/DePayRouterV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ contract DePayRouterV2 is Ownable {
// Address representing the NATIVE token (e.g. ETH, BNB, MATIC, etc.)
address public constant NATIVE = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

// Address of the WRAPPED native token (e.g. WETH, WBNB, etc.)
address public immutable WRAPPED;
// Address of the FORWARDER contract
address public immutable FORWARDER;

// List of approved exchanges for conversion
mapping (address => bool) public exchanges;

// Pass the address to the WRAPPED token standard upon initialization
constructor (address _WRAPPED) {
WRAPPED = _WRAPPED;
// Pass the forwarder contract address upon initialization
constructor (address _FORWARDER) {
FORWARDER = _FORWARDER;
}

// Accepts NATIVE payments, which is required in order to swap from and to NATIVE, especially unwrapping as part of conversions
Expand Down Expand Up @@ -68,7 +68,7 @@ contract DePayRouterV2 is Ownable {
// 0: exchangeCallData,
// 1: receiverCallData
// ]
bytes[] calldata calls,
bytes[] calldata callData,

// timestamp after which the payment will be declined
uint256 deadline
Expand Down Expand Up @@ -106,14 +106,14 @@ contract DePayRouterV2 is Ownable {
require(exchanges[addresses[1]], 'DePay: Exchange has not been approved!');
bool success;
if(addresses[0] == NATIVE) {
(success,) = addresses[1].call{value: msg.value}(calls[0]);
(success,) = addresses[1].call{value: msg.value}(callData[0]);
} else {
if(types[0] == 1) { // pull
IERC20(addresses[0]).safeApprove(addresses[1], amounts[0]);
} else if(types[0] == 2) { // push
IERC20(addresses[0]).safeTransfer(addresses[1], amounts[0]);
}
(success,) = addresses[1].call(calls[0]);
(success,) = addresses[1].call(callData[0]);
}
require(success, "DePay: exchange call failed!");
}
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,15 @@
"devDependencies": {
"@depay/web3-blockchains": "^8.4.0",
"@depay/web3-client-evm": "^10.16.3",
"@depay/web3-exchanges-evm": "^13.2.0",
"@depay/web3-exchanges-evm": "^13.2.1",
"@depay/web3-tokens-evm": "^10.1.0",
"@nomiclabs/hardhat-ethers": "^2.0.2",
"@nomiclabs/hardhat-etherscan": "^2.1.1",
"@nomiclabs/hardhat-waffle": "^2.0.1",
"@typechain/ethers-v5": "^4.0.0",
"@types/chai": "^4.2.6",
"@types/mocha": "^5.2.7",
"@types/sinon-chai": "^3.2.9",
"chai": "^4.2.0",
"decimal.js": "^10.2.1",
"dotenv": "^16.3.0",
Expand Down
2 changes: 1 addition & 1 deletion test/_approve-exchange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default ({ blockchain })=>{
})

it('deploys router successfully', async ()=> {
router = await deployRouter({ WRAPPED })
router = await deployRouter()
})

it('only allows the owner to approve exchanges', async ()=> {
Expand Down
2 changes: 1 addition & 1 deletion test/_deadline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default ({ blockchain })=>{
})

it('deploys router successfully', async ()=> {
router = await deployRouter({ WRAPPED })
router = await deployRouter()
})

it('fails if payment deadline has passed', async ()=> {
Expand Down
28 changes: 17 additions & 11 deletions test/_helpers/callData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,23 @@ export default ({
params
})=> {
const contract = new ethers.Contract(address, api, provider)
if(contract[method] === undefined){
let fragment = contract.interface.fragments.find((fragment) => {
return fragment.name == method
let contractMethod
let fragment
fragment = contract.interface.fragments.find((fragment) => {
return(
fragment.name == method &&
(fragment.inputs && params && typeof(params) === 'object' ? fragment.inputs.length == Object.keys(params).length : true)
)
})
let paramsToEncode
if(fragment.inputs.length === 1 && fragment.inputs[0].type === 'tuple') {
paramsToEncode = [params[fragment.inputs[0].name]]
contractMethod = method
} else {
paramsToEncode = fragment.inputs.map((input) => {
return params[input.name]
})
method = `${method}(${fragment.inputs.map((input)=>input.type).join(',')})`;
contractMethod = `${method}(${fragment.inputs.map((input)=>input.type).join(',')})`
}
let fragment = contract.interface.fragments.find((fragment) => {
return fragment.name == method || `${fragment.name}(${fragment.inputs.map((input)=>input.type).join(',')})` == method
})
const paramsAsArray = fragment.inputs.map((input) => {
return params[input.name]
})
return contract.interface.encodeFunctionData(method, paramsAsArray)
return contract.interface.encodeFunctionData(contractMethod, paramsToEncode)
}
6 changes: 4 additions & 2 deletions test/_helpers/deploy/router.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { ethers } from 'hardhat'

export default async ({ WRAPPED }) => {
const FORWARDER = '0x0000000000000000000000000000000000000000'

export default async () => {
const Router = await ethers.getContractFactory('DePayRouterV2')
const router = await Router.deploy(WRAPPED)
const router = await Router.deploy(FORWARDER)
await router.deployed()

return router
Expand Down
Loading

0 comments on commit 1ab9fce

Please sign in to comment.