Skip to content

Commit

Permalink
add first test for swap payment conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
vrolland committed Apr 9, 2021
1 parent 69aec47 commit 13f49e8
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 47 deletions.
13 changes: 10 additions & 3 deletions packages/payment-processor/src/payment/swap-any-to-erc20.ts
Expand Up @@ -11,7 +11,7 @@ import {
getSigner,
validateConversionFeeProxyRequest,
} from './utils';
import { getConversionPath } from '@requestnetwork/currency';
import { getDecimalsForCurrency, getConversionPath } from '@requestnetwork/currency';
import { IRequestPaymentOptions } from './settings';

export { ISwapSettings } from './swap-erc20-fee-proxy';
Expand Down Expand Up @@ -90,8 +90,15 @@ export function encodeSwapToPayAnyToErc20Request(
const { paymentReference, paymentAddress, feeAddress, feeAmount } = getRequestPaymentValues(
request,
);
const amountToPay = getAmountToPay(request, options?.amount);
const feeToPay = BigNumber.from(options?.feeAmount || feeAmount || 0);

const chainlinkDecimal = 8;
const decimalPadding = Math.max(
chainlinkDecimal - getDecimalsForCurrency(request.currencyInfo),
0,
);

const amountToPay = getAmountToPay(request, options?.amount).mul(10 ** decimalPadding);
const feeToPay = BigNumber.from(options?.feeAmount || feeAmount || 0).mul(10 ** decimalPadding);

if (
swapSettings.path[swapSettings.path.length - 1].toLowerCase() !==
Expand Down
93 changes: 56 additions & 37 deletions packages/payment-processor/test/payment/swap-any-to-erc20.test.ts
Expand Up @@ -7,18 +7,16 @@ import {
PaymentTypes,
RequestLogicTypes,
} from '@requestnetwork/types';
// import Utils from '@requestnetwork/utils';

// import { getErc20Balance } from '../../src/payment/erc20';
import { approveErc20ForSwapWithConversionIfNeeded } from '../../src/payment/swap-conversion-erc20';
import { ERC20__factory } from '@requestnetwork/smart-contracts/types';
import { ISwapSettings, swapToPayAnyToErc20Request } from '../../src/payment/swap-any-to-erc20';
import { swapToPayAnyToErc20Request } from '../../src/payment/swap-any-to-erc20';

/* eslint-disable no-magic-numbers */
/* eslint-disable @typescript-eslint/no-unused-expressions */

const erc20BeforeSwap = '0x9FBDa871d559710256a2502A2517b794B482Db40';
const erc20BeforeConversion = '0x38cF23C52Bb4B13F051Aec09580a2dE845a7FA35';
const erc20AfterConversion = '0x38cF23C52Bb4B13F051Aec09580a2dE845a7FA35';

const mnemonic = 'candy maple cake sugar pudding cream honey rich smooth crumble sweet treat';
const paymentAddress = '0xf17f52151EbEF6C7334FAD080c5704D77216b732';
Expand Down Expand Up @@ -54,8 +52,7 @@ const validRequest: ClientTypes.IRequestData = {
feeAmount: '2',
paymentAddress,
salt: 'salt',
acceptedTokens: [erc20BeforeConversion],
// TODO missing stuff here !
acceptedTokens: [erc20AfterConversion],
network: 'private',
},
version: '1.0',
Expand All @@ -72,12 +69,6 @@ const validRequest: ClientTypes.IRequestData = {
version: '1.0',
};

const validSwapSettings: ISwapSettings = {
deadline: 2599732187000, // This test will fail in 2052
maxInputAmount: 204,
path: [erc20BeforeSwap, erc20BeforeConversion],
};

describe('swap-any-to-erc20', () => {
describe('swapErc20FeeProxyRequest', () => {
it('should swap and pay with an ERC20 request with fees', async () => {
Expand All @@ -89,59 +80,87 @@ describe('swap-any-to-erc20', () => {
wallet.provider,
BigNumber.from(204).mul(BigNumber.from(10).pow(18)),
);
expect(approvalTx).toBeDefined();
// expect(approvalTx).toBeDefined();
if (approvalTx) {
await approvalTx.wait(1);
}

// get the balances to compare after payment
const balanceEthBefore = await wallet.getBalance();
const balanceAlphaBefore = await ERC20__factory.connect(
const balancePayerBSwapBefore = await ERC20__factory.connect(
erc20BeforeSwap,
provider,
).balanceOf(wallet.address);
// const issuerBalanceErc20Before = await getErc20Balance(
// validRequest,
// paymentAddress,
// provider,
// );
// const feeBalanceErc20Before = await getErc20Balance(validRequest, feeAddress, provider);
const balancePayeeAConversionBefore = await ERC20__factory.connect(
erc20AfterConversion,
provider,
).balanceOf(paymentAddress);
const balanceFeeAConversionBefore = await ERC20__factory.connect(
erc20AfterConversion,
provider,
).balanceOf(feeAddress);

// Swap and pay
const tx = await swapToPayAnyToErc20Request(validRequest, wallet, {
swap: validSwapSettings,
swap: {
deadline: 2599732187000, // This test will fail in 2052
maxInputAmount: '3000000000000000000',
path: [erc20BeforeSwap, erc20AfterConversion],
},
conversion: {
currency: {
type: 'ERC20' as any,
value: erc20BeforeConversion,
value: erc20AfterConversion,
network: 'private',
}
},
overrides: {
gasLimit: 1000000
}
})

const confirmedTx = await tx.wait(1);

expect(confirmedTx.status).toEqual(1);
expect(tx.hash).toBeDefined();

// Get the new balances
const balanceEthAfter = await wallet.getBalance();
const balanceAlphaAfter = await ERC20__factory.connect(erc20BeforeSwap, provider).balanceOf(
const balancePayerBSwapAfter = await ERC20__factory.connect(erc20BeforeSwap, provider).balanceOf(
wallet.address,
);
// const issuerBalanceErc20After = await getErc20Balance(validRequest, paymentAddress, provider);
// const feeBalanceErc20After = await getErc20Balance(validRequest, feeAddress, provider);

const balancePayeeAConversionAfter = await ERC20__factory.connect(erc20AfterConversion, provider).balanceOf(
paymentAddress,
);
const balanceFeeAConversionAfter = await ERC20__factory.connect(erc20AfterConversion, provider).balanceOf(
feeAddress,
);

// Check each balance
expect(BigNumber.from(balanceEthBefore).sub(balanceEthAfter).toNumber()).toBeGreaterThan(0);
expect(BigNumber.from(balanceAlphaAfter).toString()).toEqual(
BigNumber.from(balanceAlphaBefore).sub(204).toString(),

// expectedAmount: 100000000
// feeAmount: + 2000000
// = 102000000 (8 decimals)
// AggDaiUsd.sol / 101000000
// = 1009900990099009900 (18 decimals)
// Swapper * 2
// = 2019801980198019800 (18 decimals) paid by payer in erc20BeforeSwap
expect(BigNumber.from(balancePayerBSwapAfter).toString()).toEqual(
BigNumber.from(balancePayerBSwapBefore).sub('2019801980198019800').toString(),
);
// expect(BigNumber.from(issuerBalanceErc20After).toString()).toEqual(
// BigNumber.from(issuerBalanceErc20Before).add(100).toString(),
// );
// expect(BigNumber.from(feeBalanceErc20After).toString()).toEqual(
// BigNumber.from(feeBalanceErc20Before).add(2).toString(),
// );

// expectedAmount: 100000000 (8 decimals)
// AggDaiUsd.sol / 101000000
// = 990099009900990099 (18 decimals) received by payee in erc20AfterConversion
expect(BigNumber.from(balancePayeeAConversionAfter).toString()).toEqual(
BigNumber.from(balancePayeeAConversionBefore).add('990099009900990099').toString(),
);

// feeAmount: 2000000 (8 decimals)
// AggDaiUsd.sol / 101000000
// = 19801980198019801 (18 decimals) received by fee address in erc20AfterConversion
expect(BigNumber.from(balanceFeeAConversionAfter).toString()).toEqual(
BigNumber.from(balanceFeeAConversionBefore).add('19801980198019801').toString(),
);

});
});
});
8 changes: 4 additions & 4 deletions packages/smart-contracts/migrations/2_deploy_contracts.js
Expand Up @@ -37,7 +37,7 @@ module.exports = async function (deployer) {
console.log('requestSubmitter Whitelisted in requestHashDeclaration');

// Deploy the ERC20 contract
const instanceTestERC20 = await deployer.deploy(erc20, 10000); // 10000 initial supply
const instanceTestERC20 = await deployer.deploy(erc20, '1000000000000000000000000000000');

// Deploy ERC20 proxy contract
const instanceRequestERC20Proxy = await deployer.deploy(ERC20Proxy);
Expand Down Expand Up @@ -85,12 +85,12 @@ module.exports = async function (deployer) {

// Swap-to-pay related contracts
// Payment erc20: ALPHA
const erc20AlphaInstance = await deployer.deploy(erc20, "10000000000000000000000000000");
const erc20AlphaInstance = await deployer.deploy(erc20, "1000000000000000000000000000000");
// Mock a swap router
await deployer.deploy(FakeSwapRouter);
// 1 ERC20 = 2 ALPHA
await erc20AlphaInstance.transfer(FakeSwapRouter.address, 2000);
await instanceTestERC20.transfer(FakeSwapRouter.address, 1000);
await erc20AlphaInstance.transfer(FakeSwapRouter.address, '20000000000000000000000000000');
await instanceTestERC20.transfer(FakeSwapRouter.address, '10000000000000000000000000000');
// SwapToPay
await deployer.deploy(ERC20SwapToPay, FakeSwapRouter.address, ERC20FeeProxy.address);
console.log('SwapToPay Contract deployed: ' + ERC20SwapToPay.address);
Expand Down
Expand Up @@ -37,6 +37,10 @@ module.exports = async function (deployer) {

await deployer.deploy(Erc20ConversionProxy, ERC20FeeProxy.address, ChainlinkConversionPath.address);

// ERC20SwapToPayWithConversion
await deployer.deploy(ERC20SwapToPayWithConversion, FakeSwapRouter.address, Erc20ConversionProxy.address);
// erc20SwapConversion
const erc20SwapConversion = await deployer.deploy(ERC20SwapToPayWithConversion, FakeSwapRouter.address, Erc20ConversionProxy.address);

await erc20SwapConversion.approvePaymentProxyToSpend('0x38cF23C52Bb4B13F051Aec09580a2dE845a7FA35');
await erc20SwapConversion.approveRouterToSpend('0x9FBDa871d559710256a2502A2517b794B482Db40');

};
2 changes: 1 addition & 1 deletion packages/smart-contracts/src/contracts/ERC20SwapToPay.sol
Expand Up @@ -135,4 +135,4 @@ contract ERC20SwapToPay is Ownable {
function setRouter(address _newSwapRouterAddress) public onlyOwner {
swapRouter = IUniswapV2Router02(_newSwapRouterAddress);
}
}
}

0 comments on commit 13f49e8

Please sign in to comment.