Skip to content

Commit 1510142

Browse files
committed
batchFees amount limited for batchNoConversion erc20 functions
1 parent 256f5d6 commit 1510142

File tree

6 files changed

+653
-507
lines changed

6 files changed

+653
-507
lines changed

packages/smart-contracts/src/contracts/BatchConversionPayments.sol

Lines changed: 18 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ pragma solidity ^0.8.4;
33

44
import './interfaces/IERC20ConversionProxy.sol';
55
import './interfaces/IEthConversionProxy.sol';
6-
import './ChainlinkConversionPath.sol';
76
import './BatchNoConversionPayments.sol';
87

98
/**
@@ -25,46 +24,9 @@ contract BatchConversionPayments is BatchNoConversionPayments {
2524

2625
IERC20ConversionProxy public paymentErc20ConversionProxy;
2726
IEthConversionProxy public paymentEthConversionProxy;
28-
ChainlinkConversionPath public chainlinkConversionPath;
2927

3028
uint256 public batchConversionFee;
3129

32-
uint256 public batchFeeAmountUSDLimit; // maybe not necessary
33-
address public USDAddress;
34-
35-
/**
36-
* @dev All the information of a request, except the feeAddress
37-
* _recipient Recipient address of the payment
38-
* _requestAmount Request amount in fiat
39-
* _path Conversion path
40-
* _paymentReference Unique reference of the payment
41-
* _feeAmount The fee amount denominated in the first currency of `_path`
42-
* _maxToSpend Maximum amount the payer wants to spend, denominated in the last currency of `_path`:
43-
* it includes fee proxy but NOT the batchConversionFee
44-
* _maxRateTimespan Max acceptable times span for conversion rates, ignored if zero
45-
*/
46-
struct ConversionDetail {
47-
address recipient;
48-
uint256 requestAmount;
49-
address[] path;
50-
bytes paymentReference;
51-
uint256 feeAmount;
52-
uint256 maxToSpend;
53-
uint256 maxRateTimespan;
54-
}
55-
56-
/**
57-
* @dev BatchNoConversionPayments contract input structure.
58-
*/
59-
struct CryptoDetails {
60-
address[] tokenAddresses;
61-
address[] recipients;
62-
uint256[] amounts;
63-
bytes[] paymentReferences;
64-
uint256[] feeAmounts;
65-
//address[][] pathsToUSD; // TODO is there another solution ?
66-
}
67-
6830
/**
6931
* @dev Used by the batchRouter to handle information for heterogeneous batches, grouped by payment network.
7032
* - paymentNetworkId: from 0 to 4, cf. `batchRouter()` method.
@@ -92,10 +54,16 @@ contract BatchConversionPayments is BatchNoConversionPayments {
9254
address _paymentEthConversionFeeProxy,
9355
address _chainlinkConversionPathAddress,
9456
address _owner
95-
) BatchNoConversionPayments(_paymentErc20Proxy, _paymentEthProxy, _owner) {
57+
)
58+
BatchNoConversionPayments(
59+
_paymentErc20Proxy,
60+
_paymentEthProxy,
61+
_chainlinkConversionPathAddress,
62+
_owner
63+
)
64+
{
9665
paymentErc20ConversionProxy = IERC20ConversionProxy(_paymentErc20ConversionProxy);
9766
paymentEthConversionProxy = IEthConversionProxy(_paymentEthConversionFeeProxy);
98-
chainlinkConversionPath = ChainlinkConversionPath(_chainlinkConversionPathAddress);
9967
batchConversionFee = 0;
10068
}
10169

@@ -125,28 +93,24 @@ contract BatchConversionPayments is BatchNoConversionPayments {
12593
for (uint256 i = 0; i < metaDetails.length; i++) {
12694
MetaDetail calldata metaConversionDetail = metaDetails[i];
12795
if (metaConversionDetail.paymentNetworkId == 0) {
128-
batchFeeAmountUSD = batchMultiERC20ConversionPayments(
96+
batchFeeAmountUSD += batchMultiERC20ConversionPayments(
12997
metaConversionDetail.conversionDetails,
13098
batchFeeAmountUSD,
13199
pathsToUSD,
132100
_feeAddress
133101
);
134102
} else if (metaConversionDetail.paymentNetworkId == 1) {
135103
batchERC20Payments(
136-
metaConversionDetail.cryptoDetails.tokenAddresses[0],
137-
metaConversionDetail.cryptoDetails.recipients,
138-
metaConversionDetail.cryptoDetails.amounts,
139-
metaConversionDetail.cryptoDetails.paymentReferences,
140-
metaConversionDetail.cryptoDetails.feeAmounts,
104+
metaConversionDetail.conversionDetails,
105+
pathsToUSD,
106+
batchFeeAmountUSD,
141107
_feeAddress
142108
);
143109
} else if (metaConversionDetail.paymentNetworkId == 2) {
144-
batchMultiERC20Payments(
145-
metaConversionDetail.cryptoDetails.tokenAddresses,
146-
metaConversionDetail.cryptoDetails.recipients,
147-
metaConversionDetail.cryptoDetails.amounts,
148-
metaConversionDetail.cryptoDetails.paymentReferences,
149-
metaConversionDetail.cryptoDetails.feeAmounts,
110+
batchFeeAmountUSD += batchMultiERC20Payments(
111+
metaConversionDetail.conversionDetails,
112+
pathsToUSD,
113+
batchFeeAmountUSD,
150114
_feeAddress
151115
);
152116
} else if (metaConversionDetail.paymentNetworkId == 3) {
@@ -176,6 +140,7 @@ contract BatchConversionPayments is BatchNoConversionPayments {
176140
* @notice Send a batch of ERC20 payments with amounts based on a request
177141
* currency (e.g. fiat), with fees and paymentReferences to multiple accounts, with multiple tokens.
178142
* @param conversionDetails list of requestInfo, each one containing all the information of a request
143+
* @param batchFeeAmountUSD The batchFeeAmountUSD already paid
179144
* @param pathsToUSD The list of paths into USD for every token
180145
* @param _feeAddress The fee recipient
181146
*/
@@ -185,26 +150,7 @@ contract BatchConversionPayments is BatchNoConversionPayments {
185150
address[][] calldata pathsToUSD,
186151
address _feeAddress
187152
) public returns (uint256) {
188-
// a list of unique tokens, with the sum of maxToSpend by token
189-
Token[] memory uTokens = new Token[](conversionDetails.length);
190-
for (uint256 i = 0; i < conversionDetails.length; i++) {
191-
for (uint256 k = 0; k < conversionDetails.length; k++) {
192-
// If the token is already in the existing uTokens list
193-
if (
194-
uTokens[k].tokenAddress == conversionDetails[i].path[conversionDetails[i].path.length - 1]
195-
) {
196-
uTokens[k].amountAndFee += conversionDetails[i].maxToSpend;
197-
break;
198-
}
199-
// If the token is not in the list (amountAndFee = 0)
200-
else if (uTokens[k].amountAndFee == 0 && (conversionDetails[i].maxToSpend) > 0) {
201-
uTokens[k].tokenAddress = conversionDetails[i].path[conversionDetails[i].path.length - 1];
202-
// amountAndFee is used to store _maxToSpend, useful to send enough tokens to this contract
203-
uTokens[k].amountAndFee = conversionDetails[i].maxToSpend;
204-
break;
205-
}
206-
}
207-
}
153+
Token[] memory uTokens = getUTokens(conversionDetails);
208154

209155
IERC20 requestedToken;
210156
// For each token: check allowance, transfer funds on the contract and approve the paymentProxy to spend if needed
@@ -327,34 +273,6 @@ contract BatchConversionPayments is BatchNoConversionPayments {
327273
payerAuthorized = false;
328274
}
329275

330-
function calculateBatchFeeToPay(
331-
uint256 batchFeeToPay,
332-
address tokenAddress,
333-
uint256 batchFeeAmountUSD,
334-
address[][] calldata pathsToUSD
335-
) internal view returns (uint256, uint256) {
336-
if (pathsToUSD.length > 0) {
337-
for (uint256 i = 0; i < pathsToUSD.length; i++) {
338-
if (
339-
pathsToUSD[i][0] == tokenAddress && pathsToUSD[i][pathsToUSD[i].length - 1] == USDAddress
340-
) {
341-
uint256 conversionUSD = 0;
342-
(conversionUSD, ) = chainlinkConversionPath.getConversion(batchFeeToPay, pathsToUSD[i]);
343-
// calculate the batch fee to pay, taking care of the batchFeeAmountUSDLimit
344-
uint256 conversionToPayUSD = conversionUSD;
345-
if (batchFeeAmountUSD + conversionToPayUSD > batchFeeAmountUSDLimit) {
346-
conversionToPayUSD = batchFeeAmountUSDLimit - batchFeeAmountUSD;
347-
batchFeeToPay = (batchFeeToPay * conversionToPayUSD) / conversionUSD;
348-
}
349-
batchFeeAmountUSD += conversionToPayUSD;
350-
// add only once the fees
351-
break;
352-
}
353-
}
354-
}
355-
return (batchFeeToPay, batchFeeAmountUSD);
356-
}
357-
358276
/*
359277
* Admin functions to edit the conversion proxies address and fees
360278
*/
@@ -390,12 +308,4 @@ contract BatchConversionPayments is BatchNoConversionPayments {
390308
function setConversionPathAddress(address _chainlinkConversionPathAddress) external onlyOwner {
391309
chainlinkConversionPath = ChainlinkConversionPath(_chainlinkConversionPathAddress);
392310
}
393-
394-
function setUSDAddress(address _USDAddress) external onlyOwner {
395-
USDAddress = _USDAddress;
396-
}
397-
398-
function setBatchFeeAmountUSDLimit(uint256 _batchFeeAmountUSDLimit) external onlyOwner {
399-
batchFeeAmountUSDLimit = _batchFeeAmountUSDLimit;
400-
}
401311
}

0 commit comments

Comments
 (0)