Skip to content

Commit

Permalink
Extended swap contract with the new behavior to be able to take fee i…
Browse files Browse the repository at this point in the history
…n a fixed amount.
  • Loading branch information
piotrwitek committed Oct 15, 2024
1 parent 6dd09cb commit 77f0636
Show file tree
Hide file tree
Showing 12 changed files with 69 additions and 6 deletions.
37 changes: 33 additions & 4 deletions packages/dma-contracts/contracts/swap/Swap.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { IERC20 } from "../interfaces/tokens/IERC20.sol";
import { SafeMath } from "../libs/SafeMath.sol";
import { SafeERC20 } from "../libs/SafeERC20.sol";
import { ONE_INCH_AGGREGATOR } from "../core/constants/Common.sol";
import { SwapData } from "../core/types/Common.sol";
import { SwapData, FeeType } from "../core/types/Common.sol";

contract Swap {
using SafeMath for uint256;
Expand All @@ -23,6 +23,7 @@ contract Swap {
error FeeTierDoesNotExist(uint256 fee);
error FeeTierAlreadyExists(uint256 fee);
error SwapFailed();
error FeeTypeDoesNotExist();

constructor(
address authorisedCaller,
Expand Down Expand Up @@ -107,7 +108,7 @@ contract Swap {
emit AssetSwap(fromAsset, toAsset, amount, balance);
}

function _collectFee(
function _collectPercentageFee(
address asset,
uint256 fromAmount,
uint256 fee
Expand All @@ -127,13 +128,41 @@ contract Swap {
amount = fromAmount.sub(feeToTransfer);
}

function _collectFixedFee(
address asset,
uint256 fromAmount,
uint256 fee
) internal returns (uint256 amount) {
amount = fromAmount.sub(fee);

if (fee > 0) {
IERC20(asset).safeTransfer(feeBeneficiaryAddress, fee);
emit FeePaid(feeBeneficiaryAddress, fee, asset);
}
}

function _collectFee(
address asset,
uint256 fromAmount,
uint256 fee,
FeeType feeType
) internal returns (uint256 amount) {
if (feeType == FeeType.Percentage) {
amount = _collectPercentageFee(asset, fromAmount, fee);
} else if (feeType == FeeType.Fixed) {
amount = _collectFixedFee(asset, fromAmount, fee);
} else {
revert FeeTypeDoesNotExist();
}
}

function swapTokens(SwapData calldata swapData) public returns (uint256) {
IERC20(swapData.fromAsset).safeTransferFrom(msg.sender, address(this), swapData.amount);

uint256 amountFrom = swapData.amount;

if (swapData.collectFeeInFromToken) {
amountFrom = _collectFee(swapData.fromAsset, swapData.amount, swapData.fee);
amountFrom = _collectFee(swapData.fromAsset, swapData.amount, swapData.fee, swapData.feeType);
}

address oneInch = registry.getRegisteredService(ONE_INCH_AGGREGATOR);
Expand All @@ -148,7 +177,7 @@ contract Swap {
);

if (!swapData.collectFeeInFromToken) {
toTokenBalance = _collectFee(swapData.toAsset, toTokenBalance, swapData.fee);
toTokenBalance = _collectFee(swapData.toAsset, toTokenBalance, swapData.fee, swapData.feeType);
}

uint256 fromTokenBalance = IERC20(swapData.fromAsset).balanceOf(address(this));
Expand Down
2 changes: 1 addition & 1 deletion packages/dma-contracts/test/config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Do not change test block numbers as they're linked to uniswap liquidity levels
import { Network } from '@deploy-configurations/types/network'

export const testBlockNumber = 15695000
export const testBlockNumber = 20971320
export const testBlockNumberForAaveV3 = 16597880

export const testBlockNumberForMigrations = 19324700
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { amountFromWei, amountToWei } from '@dma-common/utils/common'
import { calculateFeeOnInputAmount } from '@dma-common/utils/swap'
import { testBlockNumber } from '@dma-contracts/test/config'
import { restoreSnapshot, TestHelpers } from '@dma-contracts/utils'
import { SwapFeeType } from '@dma-library/types'
import { Contract } from '@ethersproject/contracts'
import { JsonRpcProvider } from '@ethersproject/providers'
import { MockExchange } from '@typechain'
Expand Down Expand Up @@ -119,6 +120,7 @@ describe('Swap | Unit', async () => {
FEE,
data,
true,
SwapFeeType.Percentage,
],
{
value: 0,
Expand Down Expand Up @@ -204,6 +206,7 @@ describe('Swap | Unit', async () => {
FEE,
data,
false,
SwapFeeType.Percentage,
],
{
value: 0,
Expand Down Expand Up @@ -300,6 +303,7 @@ describe('Swap | Unit', async () => {
FEE,
data,
true,
SwapFeeType.Percentage,
],
{
value: 0,
Expand Down Expand Up @@ -404,6 +408,7 @@ describe('Swap | Unit', async () => {
FEE,
data,
true,
SwapFeeType.Percentage,
],
{
value: 0,
Expand Down Expand Up @@ -494,6 +499,7 @@ describe('Swap | Unit', async () => {
FEE,
data,
true,
SwapFeeType.Percentage,
],
{
value: 0,
Expand Down Expand Up @@ -547,6 +553,7 @@ describe('Swap | Unit', async () => {
FEE,
data,
true,
SwapFeeType.Percentage,
],
{
value: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { balanceOf } from '@dma-common/utils/balances'
import { amountToWei } from '@dma-common/utils/common'
import { testBlockNumber } from '@dma-contracts/test/config'
import { restoreSnapshot, TestHelpers } from '@dma-contracts/utils'
import { SwapFeeType } from '@dma-library/types'
import { Contract } from '@ethersproject/contracts'
import { MockExchange } from '@typechain'
import BigNumber from 'bignumber.js'
Expand Down Expand Up @@ -98,6 +99,7 @@ describe('Swap | Unit', async () => {
FEE,
data,
true,
SwapFeeType.Percentage,
],
{
value: 0,
Expand All @@ -123,6 +125,7 @@ describe('Swap | Unit', async () => {
FEE,
data,
true,
SwapFeeType.Percentage,
],
{
value: 0,
Expand Down Expand Up @@ -154,6 +157,7 @@ describe('Swap | Unit', async () => {
FEE,
response.tx.data,
true,
SwapFeeType.Percentage,
])

const expectedRevert = /ReceivedLess\(100000000000000000000000, \d+\)/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { amountFromWei, amountToWei } from '@dma-common/utils/common'
import { calculateFeeOnInputAmount } from '@dma-common/utils/swap'
import { testBlockNumber } from '@dma-contracts/test/config'
import { restoreSnapshot, TestHelpers } from '@dma-contracts/utils'
import { SwapFeeType } from '@dma-library/types'
import { Contract } from '@ethersproject/contracts'
import { JsonRpcProvider } from '@ethersproject/providers'
import { MockExchange } from '@typechain'
Expand Down Expand Up @@ -117,6 +118,7 @@ describe('Swap | Unit', async () => {
FEE,
data,
true,
SwapFeeType.Percentage,
])
})

Expand Down Expand Up @@ -208,6 +210,7 @@ describe('Swap | Unit', async () => {
FEE,
data,
true,
SwapFeeType.Percentage,
],
{
value: 0,
Expand Down Expand Up @@ -325,6 +328,7 @@ describe('Swap | Unit', async () => {
FEE,
data,
true,
SwapFeeType.Percentage,
],
{
value: 0,
Expand Down Expand Up @@ -399,6 +403,7 @@ describe('Swap | Unit', async () => {
FEE,
data,
true,
SwapFeeType.Percentage,
],
{
value: 0,
Expand Down Expand Up @@ -438,6 +443,7 @@ describe('Swap | Unit', async () => {
FEE,
data,
true,
SwapFeeType.Percentage,
],
{
value: 0,
Expand Down Expand Up @@ -503,6 +509,7 @@ describe('Swap | Unit', async () => {
FEE,
data,
true,
SwapFeeType.Percentage,
],
{
value: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { amountFromWei, amountToWei } from '@dma-common/utils/common'
import { calculateFeeOnInputAmount } from '@dma-common/utils/swap'
import { testBlockNumber } from '@dma-contracts/test/config'
import { restoreSnapshot, TestHelpers } from '@dma-contracts/utils'
import { SwapFeeType } from '@dma-library/types'
import { Contract } from '@ethersproject/contracts'
import { MockExchange } from '@typechain'
import BigNumber from 'bignumber.js'
Expand Down Expand Up @@ -106,6 +107,7 @@ describe('Swap | Unit', async () => {
FEE,
data,
true,
SwapFeeType.Percentage,
],
{
value: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { amountFromWei, amountToWei } from '@dma-common/utils/common'
import { calculateFeeOnInputAmount } from '@dma-common/utils/swap'
import { testBlockNumber } from '@dma-contracts/test/config'
import { restoreSnapshot, TestHelpers } from '@dma-contracts/utils'
import { SwapFeeType } from '@dma-library/types'
import { Contract } from '@ethersproject/contracts'
import { MockExchange } from '@typechain'
import BigNumber from 'bignumber.js'
Expand Down Expand Up @@ -111,6 +112,7 @@ describe('Swap | Unit', async () => {
FEE,
data,
true,
SwapFeeType.Percentage,
],
{
value: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { amountFromWei, amountToWei } from '@dma-common/utils/common'
import { calculateFee } from '@dma-common/utils/swap'
import { testBlockNumber } from '@dma-contracts/test/config'
import { restoreSnapshot, TestHelpers } from '@dma-contracts/utils'
import { SwapFeeType } from '@dma-library/types'
import { MockExchange } from '@typechain'
import BigNumber from 'bignumber.js'
import { Contract, Signer } from 'ethers'
Expand Down Expand Up @@ -107,6 +108,7 @@ describe('Swap | Unit', async () => {
FEE,
data,
true,
SwapFeeType.Percentage,
],
{
value: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { amountToWei } from '@dma-common/utils/common'
import { calculateFeeOnInputAmount } from '@dma-common/utils/swap'
import { testBlockNumber } from '@dma-contracts/test/config'
import { restoreSnapshot, TestHelpers } from '@dma-contracts/utils'
import { SwapFeeType } from '@dma-library/types'
import { Contract } from '@ethersproject/contracts'
import { JsonRpcProvider } from '@ethersproject/providers'
import { MockExchange } from '@typechain'
Expand Down Expand Up @@ -168,6 +169,7 @@ describe('Swap | Unit', async () => {
fee,
response.tx.data,
true,
SwapFeeType.Percentage,
],
{
value: 0,
Expand Down Expand Up @@ -215,6 +217,7 @@ describe('Swap | Unit', async () => {
fee,
response.tx.data,
true,
SwapFeeType.Percentage,
],
{
value: 0,
Expand Down
4 changes: 3 additions & 1 deletion packages/dma-library/src/actions/common.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { loadContractNames } from '@deploy-configurations/constants'
import { Network } from '@deploy-configurations/types/network'
import { getActionHash } from '@deploy-configurations/utils/action-hash'
import { ActionCall, calldataTypes } from '@dma-library/types'
import { ActionCall, calldataTypes, SwapFeeType } from '@dma-library/types'
import BigNumber from 'bignumber.js'

import { ActionFactory } from './action-factory'
Expand Down Expand Up @@ -80,6 +80,7 @@ export function swap(
fee: number
withData: string | number
collectFeeInFromToken: boolean
feeType: SwapFeeType
},
) {
const SERVICE_REGISTRY_NAMES = loadContractNames(network)
Expand All @@ -96,6 +97,7 @@ export function swap(
fee: args.fee,
withData: args.withData,
collectFeeInFromToken: args.collectFeeInFromToken,
feeType: args.feeType ?? SwapFeeType.Percentage,
},
],
)
Expand Down
1 change: 1 addition & 0 deletions packages/dma-library/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export type {
WithWithdrawCollateral,
}
export type { SwapData }
export { SwapFeeType } from './swap-fee-type'
export type { Swap }

export { MorphoBluePosition }
Expand Down
4 changes: 4 additions & 0 deletions packages/dma-library/src/types/swap-fee-type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum SwapFeeType {
Percentage = 0,
Fixed = 1,
}

0 comments on commit 77f0636

Please sign in to comment.