Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Payment netwrok any-to-eth smartcontracts
- Loading branch information
Showing
7 changed files
with
554 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { HardhatRuntimeEnvironment } from 'hardhat/types'; | ||
import { deployOne } from './deploy-one'; | ||
|
||
export default async function deploy( | ||
args: { chainlinkConversionPathAddress?: string; ethFeeProxyAddress?: string }, | ||
hre: HardhatRuntimeEnvironment, | ||
) { | ||
const contractName = 'EthConversionProxy'; | ||
|
||
if (!args.chainlinkConversionPathAddress) { | ||
// FIXME: should try to retrieve information from artifacts instead | ||
console.error( | ||
`Missing ChainlinkConversionPath on ${hre.network.name}, cannot deploy ${contractName}.`, | ||
); | ||
return; | ||
} | ||
if (!args.ethFeeProxyAddress) { | ||
// FIXME: should try to retrieve information from artifacts instead | ||
console.error(`Missing EthereumFeeProxy on ${hre.network.name}, cannot deploy ${contractName}.`); | ||
return; | ||
} | ||
|
||
return deployOne(args, hre, contractName, [ | ||
args.ethFeeProxyAddress, | ||
args.chainlinkConversionPathAddress, | ||
]); | ||
} |
122 changes: 122 additions & 0 deletions
122
packages/smart-contracts/src/contracts/EthConversionProxy.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import "./ChainlinkConversionPath.sol"; | ||
import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; | ||
|
||
/** | ||
* @title EthConversionProxy | ||
* @notice This contract convert from chainlink then swaps ETH | ||
* before paying a request thanks to a conversion payment proxy | ||
* the dependance with ReentrancyGuard is required to perform | ||
* "transferExactEthWithReferenceAndFee" of the eth-fee-proxy contract | ||
*/ | ||
contract EthConversionProxy is ReentrancyGuard { | ||
address public paymentProxy; | ||
ChainlinkConversionPath public chainlinkConversionPath; | ||
|
||
constructor(address _paymentProxyAddress, address _chainlinkConversionPathAddress) { | ||
paymentProxy = _paymentProxyAddress; | ||
chainlinkConversionPath = ChainlinkConversionPath(_chainlinkConversionPathAddress); | ||
} | ||
|
||
// Event to declare a conversion with a reference | ||
event TransferWithConversionAndReference( | ||
uint256 amount, | ||
address currency, | ||
bytes indexed paymentReference, | ||
uint256 feeAmount, | ||
uint256 maxRateTimespan | ||
); | ||
|
||
// Event to declare a transfer with a reference | ||
event TransferWithReferenceAndFee( | ||
address to, | ||
uint256 amount, | ||
bytes indexed paymentReference, | ||
uint256 feeAmount, | ||
address feeAddress | ||
); | ||
|
||
/** | ||
* @notice Performs an ETH transfer with a reference computing the payment amount based on the request amount | ||
* @param _to Transfer recipient of the payement | ||
* @param _requestAmount Request amount | ||
* @param _path Conversion path | ||
* @param _paymentReference Reference of the payment related | ||
* @param _feeAmount The amount of the payment fee | ||
* @param _feeAddress The fee recipient | ||
* @param _maxRateTimespan Max time span with the oldestrate, ignored if zero | ||
*/ | ||
function transferWithReferenceAndFee( | ||
address _to, | ||
uint256 _requestAmount, | ||
address[] calldata _path, | ||
bytes calldata _paymentReference, | ||
uint256 _feeAmount, | ||
address _feeAddress, | ||
uint256 _maxRateTimespan | ||
) | ||
external | ||
payable | ||
{ | ||
// Request currency hash for ether: 0xF5AF88e117747e87fC5929F2ff87221B1447652E | ||
require( | ||
_path[_path.length - 1] == address(0xF5AF88e117747e87fC5929F2ff87221B1447652E), | ||
"payment currency must be ethers" | ||
); | ||
|
||
(uint256 amountToPay, uint256 amountToPayInFees) = getConversions( | ||
_path, | ||
_requestAmount, | ||
_feeAmount, | ||
_maxRateTimespan); | ||
|
||
// Pay the request and fees | ||
(bool status, ) = paymentProxy.delegatecall( | ||
abi.encodeWithSignature( | ||
"transferExactEthWithReferenceAndFee(address,uint256,bytes,uint256,address)", | ||
_to, | ||
amountToPay, | ||
_paymentReference, | ||
amountToPayInFees, | ||
_feeAddress | ||
) | ||
); | ||
|
||
require(status, "paymentProxy transferExactEthWithReferenceAndFee failed"); | ||
|
||
// Event to declare a transfer with a reference | ||
emit TransferWithConversionAndReference( | ||
_requestAmount, | ||
// request currency | ||
_path[0], | ||
_paymentReference, | ||
_feeAmount, | ||
_maxRateTimespan | ||
); | ||
} | ||
|
||
function getConversions( | ||
address[] memory _path, | ||
uint256 _requestAmount, | ||
uint256 _feeAmount, | ||
uint256 _maxRateTimespan | ||
) | ||
internal | ||
view | ||
returns (uint256 amountToPay, uint256 amountToPayInFees) | ||
{ | ||
(uint256 rate, uint256 oldestTimestampRate, uint256 decimals) = chainlinkConversionPath.getRate(_path); | ||
|
||
// Check rate timespan | ||
require( | ||
_maxRateTimespan == 0 || block.timestamp - oldestTimestampRate <= _maxRateTimespan, | ||
"aggregator rate is outdated" | ||
); | ||
|
||
// Get the amount to pay in the crypto currency chosen | ||
amountToPay = (_requestAmount * rate) / decimals; | ||
amountToPayInFees = (_feeAmount * rate) /decimals; | ||
} | ||
} |
163 changes: 163 additions & 0 deletions
163
packages/smart-contracts/src/lib/artifacts/EthConversionProxy/0.1.0.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
{ | ||
"abi": [ | ||
{ | ||
"inputs": [ | ||
{ | ||
"internalType": "address", | ||
"name": "_paymentProxyAddress", | ||
"type": "address" | ||
}, | ||
{ | ||
"internalType": "address", | ||
"name": "_chainlinkConversionPathAddress", | ||
"type": "address" | ||
} | ||
], | ||
"stateMutability": "nonpayable", | ||
"type": "constructor" | ||
}, | ||
{ | ||
"anonymous": false, | ||
"inputs": [ | ||
{ | ||
"indexed": false, | ||
"internalType": "uint256", | ||
"name": "amount", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"indexed": false, | ||
"internalType": "address", | ||
"name": "currency", | ||
"type": "address" | ||
}, | ||
{ | ||
"indexed": true, | ||
"internalType": "bytes", | ||
"name": "paymentReference", | ||
"type": "bytes" | ||
}, | ||
{ | ||
"indexed": false, | ||
"internalType": "uint256", | ||
"name": "feeAmount", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"indexed": false, | ||
"internalType": "uint256", | ||
"name": "maxRateTimespan", | ||
"type": "uint256" | ||
} | ||
], | ||
"name": "TransferWithConversionAndReference", | ||
"type": "event" | ||
}, | ||
{ | ||
"anonymous": false, | ||
"inputs": [ | ||
{ | ||
"indexed": false, | ||
"internalType": "address", | ||
"name": "to", | ||
"type": "address" | ||
}, | ||
{ | ||
"indexed": false, | ||
"internalType": "uint256", | ||
"name": "amount", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"indexed": true, | ||
"internalType": "bytes", | ||
"name": "paymentReference", | ||
"type": "bytes" | ||
}, | ||
{ | ||
"indexed": false, | ||
"internalType": "uint256", | ||
"name": "feeAmount", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"indexed": false, | ||
"internalType": "address", | ||
"name": "feeAddress", | ||
"type": "address" | ||
} | ||
], | ||
"name": "TransferWithReferenceAndFee", | ||
"type": "event" | ||
}, | ||
{ | ||
"inputs": [], | ||
"name": "chainlinkConversionPath", | ||
"outputs": [ | ||
{ | ||
"internalType": "contract ChainlinkConversionPath", | ||
"name": "", | ||
"type": "address" | ||
} | ||
], | ||
"stateMutability": "view", | ||
"type": "function" | ||
}, | ||
{ | ||
"inputs": [], | ||
"name": "paymentProxy", | ||
"outputs": [ | ||
{ | ||
"internalType": "address", | ||
"name": "", | ||
"type": "address" | ||
} | ||
], | ||
"stateMutability": "view", | ||
"type": "function" | ||
}, | ||
{ | ||
"inputs": [ | ||
{ | ||
"internalType": "address", | ||
"name": "_to", | ||
"type": "address" | ||
}, | ||
{ | ||
"internalType": "uint256", | ||
"name": "_requestAmount", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"internalType": "address[]", | ||
"name": "_path", | ||
"type": "address[]" | ||
}, | ||
{ | ||
"internalType": "bytes", | ||
"name": "_paymentReference", | ||
"type": "bytes" | ||
}, | ||
{ | ||
"internalType": "uint256", | ||
"name": "_feeAmount", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"internalType": "address", | ||
"name": "_feeAddress", | ||
"type": "address" | ||
}, | ||
{ | ||
"internalType": "uint256", | ||
"name": "_maxRateTimespan", | ||
"type": "uint256" | ||
} | ||
], | ||
"name": "transferWithReferenceAndFee", | ||
"outputs": [], | ||
"stateMutability": "payable", | ||
"type": "function" | ||
} | ||
] | ||
} |
19 changes: 19 additions & 0 deletions
19
packages/smart-contracts/src/lib/artifacts/EthConversionProxy/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { ContractArtifact } from '../../ContractArtifact'; | ||
|
||
import { abi as ABI_0_1_0 } from './0.1.0.json'; | ||
import type { EthConversionProxy } from '../../../types/EthConversionProxy'; | ||
|
||
export const ethConversionArtifact = new ContractArtifact<EthConversionProxy>( | ||
{ | ||
'0.1.0': { | ||
abi: ABI_0_1_0, | ||
deployment: { | ||
private: { | ||
address: '0x8273e4B8ED6c78e252a9fCa5563Adfcc75C91b2A', | ||
creationBlockNumber: 0, | ||
}, | ||
}, | ||
}, | ||
}, | ||
'0.1.0', | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.