Skip to content

Commit

Permalink
optional staking token for swap-erc20
Browse files Browse the repository at this point in the history
  • Loading branch information
dmosites committed Oct 8, 2023
1 parent 2e886e5 commit 29ea0b5
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 66 deletions.
28 changes: 12 additions & 16 deletions source/swap-erc20/contracts/SwapERC20.sol
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ contract SwapERC20 is ISwapERC20, Ownable, EIP712 {
address public protocolFeeWallet;
uint256 public discountScale;
uint256 public discountMax;
address public staking;
address public stakingToken;

/**
* @notice Constructor
Expand All @@ -56,22 +56,19 @@ contract SwapERC20 is ISwapERC20, Ownable, EIP712 {
* @param _protocolFeeWallet address destination for fees
* @param _discountScale uin256 scale factor for discount
* @param _discountMax uint256 max discount percentage
* @param _staking address staking contract address
*/
constructor(
uint256 _protocolFee,
uint256 _protocolFeeLight,
address _protocolFeeWallet,
uint256 _discountScale,
uint256 _discountMax,
address _staking
uint256 _discountMax
) EIP712(DOMAIN_NAME, DOMAIN_VERSION) {
if (_protocolFee >= FEE_DIVISOR) revert InvalidFee();
if (_protocolFeeLight >= FEE_DIVISOR) revert InvalidFeeLight();
if (_protocolFeeWallet == address(0)) revert InvalidFeeWallet();
if (_discountMax > MAX_MAX) revert MaxTooHigh();
if (_discountScale > MAX_SCALE) revert ScaleTooHigh();
if (_staking == address(0)) revert InvalidStaking();

DOMAIN_CHAIN_ID = block.chainid;
DOMAIN_SEPARATOR = _domainSeparatorV4();
Expand All @@ -81,7 +78,6 @@ contract SwapERC20 is ISwapERC20, Ownable, EIP712 {
protocolFeeWallet = _protocolFeeWallet;
discountMax = _discountMax;
discountScale = _discountScale;
staking = _staking;
}

/**
Expand Down Expand Up @@ -346,13 +342,13 @@ contract SwapERC20 is ISwapERC20, Ownable, EIP712 {

/**
* @notice Set the staking token
* @param newstaking address Token to check balances on
* @param _stakingToken address Token to check balances on
*/
function setStaking(address newstaking) external onlyOwner {
function setStaking(address _stakingToken) external onlyOwner {
// Ensure the new staking token is not null
if (newstaking == address(0)) revert InvalidStaking();
staking = newstaking;
emit SetStaking(newstaking);
if (_stakingToken == address(0)) revert InvalidStaking();
stakingToken = _stakingToken;
emit SetStaking(_stakingToken);
}

/**
Expand Down Expand Up @@ -543,7 +539,7 @@ contract SwapERC20 is ISwapERC20, Ownable, EIP712 {
}

/**
* @notice Calculates and refers fee amount
* @notice Calculates protocol fee for an account
* @param wallet address
* @param amount uint256
*/
Expand All @@ -553,9 +549,9 @@ contract SwapERC20 is ISwapERC20, Ownable, EIP712 {
) public view override returns (uint256) {
// Transfer fee from signer to feeWallet
uint256 feeAmount = (amount * protocolFee) / FEE_DIVISOR;
if (feeAmount > 0) {
if (stakingToken != address(0) && feeAmount > 0) {
uint256 discountAmount = calculateDiscount(
IERC20(staking).balanceOf(wallet),
IERC20(stakingToken).balanceOf(wallet),
feeAmount
);
return feeAmount - discountAmount;
Expand Down Expand Up @@ -723,9 +719,9 @@ contract SwapERC20 is ISwapERC20, Ownable, EIP712 {
) internal {
// Transfer fee from signer to feeWallet
uint256 feeAmount = (amount * protocolFee) / FEE_DIVISOR;
if (feeAmount > 0) {
if (stakingToken != address(0) && feeAmount > 0) {
uint256 discountAmount = calculateDiscount(
IERC20(staking).balanceOf(msg.sender),
IERC20(stakingToken).balanceOf(msg.sender),
feeAmount
);
if (discountAmount > 0) {
Expand Down
62 changes: 20 additions & 42 deletions source/swap-erc20/test/SwapERC20.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,7 @@ describe('SwapERC20 Unit', () => {
PROTOCOL_FEE_LIGHT,
protocolFeeWallet.address,
REBATE_SCALE,
REBATE_MAX,
staking.address
REBATE_MAX
)
await swap.deployed()
})
Expand All @@ -149,8 +148,7 @@ describe('SwapERC20 Unit', () => {
PROTOCOL_FEE_LIGHT,
ADDRESS_ZERO,
REBATE_SCALE,
REBATE_MAX,
staking.address
REBATE_MAX
)
).to.be.revertedWith('InvalidFeeWallet')
})
Expand All @@ -164,8 +162,7 @@ describe('SwapERC20 Unit', () => {
PROTOCOL_FEE_LIGHT,
protocolFeeWallet.address,
REBATE_SCALE,
REBATE_MAX,
staking.address
REBATE_MAX
)
).to.be.revertedWith('InvalidFee')
})
Expand All @@ -179,8 +176,7 @@ describe('SwapERC20 Unit', () => {
100000000000,
protocolFeeWallet.address,
REBATE_SCALE,
REBATE_MAX,
staking.address
REBATE_MAX
)
).to.be.revertedWith('InvalidFeeLight')
})
Expand All @@ -194,8 +190,7 @@ describe('SwapERC20 Unit', () => {
PROTOCOL_FEE_LIGHT,
protocolFeeWallet.address,
REBATE_SCALE + 1,
REBATE_MAX,
staking.address
REBATE_MAX
)
).to.be.revertedWith('ScaleTooHigh')
})
Expand All @@ -209,26 +204,10 @@ describe('SwapERC20 Unit', () => {
PROTOCOL_FEE_LIGHT,
protocolFeeWallet.address,
REBATE_SCALE,
REBATE_MAX + 1,
staking.address
REBATE_MAX + 1
)
).to.be.revertedWith('MaxTooHigh')
})

it('test invalid discount maximum', async () => {
await expect(
(
await ethers.getContractFactory('SwapERC20')
).deploy(
PROTOCOL_FEE,
PROTOCOL_FEE_LIGHT,
protocolFeeWallet.address,
REBATE_SCALE,
REBATE_MAX,
ADDRESS_ZERO
)
).to.be.revertedWith('InvalidStaking')
})
})

describe('Test setters', async () => {
Expand Down Expand Up @@ -312,8 +291,18 @@ describe('SwapERC20 Unit', () => {
})

describe('Test calculateProtocolFee', async () => {
it('test calculateProtocolFee without staking set', async () => {
const feeAmount = await swap
.connect(deployer)
.calculateProtocolFee(sender.address, DEFAULT_AMOUNT)
expect(feeAmount).to.equal((DEFAULT_AMOUNT * PROTOCOL_FEE) / FEE_DIVISOR)
})
it('test calculateProtocolFee', async () => {
const initialFeeAmount = (DEFAULT_AMOUNT * PROTOCOL_FEE) / FEE_DIVISOR
await expect(swap.connect(deployer).setStaking(staking.address)).to.emit(
swap,
'SetStaking'
)
const discount = await swap
.connect(deployer)
.calculateDiscount(10000000, initialFeeAmount)
Expand All @@ -324,6 +313,10 @@ describe('SwapERC20 Unit', () => {
})
it('test calculateProtocolFee with protocol fee as zero', async () => {
const zeroProtocolFee = 0
await expect(swap.connect(deployer).setStaking(staking.address)).to.emit(
swap,
'SetStaking'
)
await swap.connect(deployer).setProtocolFee(zeroProtocolFee)
const initialFeeAmount = (DEFAULT_AMOUNT * zeroProtocolFee) / FEE_DIVISOR
const discount = await swap
Expand Down Expand Up @@ -635,21 +628,6 @@ describe('SwapERC20 Unit', () => {
'Unauthorized'
)
})

it('test swaps gas consumption', async () => {
const order = await createSignedOrderERC20(
{
protocolFee: PROTOCOL_FEE_LIGHT,
},
signer
)

const transaction = await swap.connect(sender).swapLight(...order)
const swapReceipt = await transaction.wait()
const swapCost = swapReceipt.gasUsed
console.log(swapCost)
expect(Number(swapCost)).to.be.lessThanOrEqual(129246)
})
})

describe('Test fees', async () => {
Expand Down
24 changes: 18 additions & 6 deletions source/swap-erc20/test/SwapERC20Integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ describe('SwapERC20 Integration', () => {
let senderToken
let staking

let deployer
let sender
let signer
let protocolFeeWallet
Expand Down Expand Up @@ -57,7 +58,7 @@ describe('SwapERC20 Integration', () => {
})

before('get signers and deploy', async () => {
;[sender, signer, protocolFeeWallet] = await ethers.getSigners()
;[deployer, sender, signer, protocolFeeWallet] = await ethers.getSigners()

stakingToken = await (
await ethers.getContractFactory(ERC20.abi, ERC20.bytecode)
Expand Down Expand Up @@ -89,8 +90,7 @@ describe('SwapERC20 Integration', () => {
PROTOCOL_FEE_LIGHT,
protocolFeeWallet.address,
DISCOUNT_SCALE,
DISCOUNT_MAX,
staking.address
DISCOUNT_MAX
)
await swap.deployed()

Expand All @@ -101,9 +101,16 @@ describe('SwapERC20 Integration', () => {
describe('Test token holder discounts', async () => {
it('test swap without discount', async () => {
const order = await createSignedOrder({}, signer)
await expect(
await swap.connect(sender).swap(sender.address, ...order)
).to.emit(swap, 'SwapERC20')

await expect(swap.connect(deployer).setStaking(staking.address)).to.emit(
swap,
'SetStaking'
)

await expect(swap.connect(sender).swap(sender.address, ...order)).to.emit(
swap,
'SwapERC20'
)

// Expect full 30 to be taken from signer
expect(await signerToken.balanceOf(signer.address)).to.equal('989970')
Expand All @@ -121,6 +128,11 @@ describe('SwapERC20 Integration', () => {
await stakingToken.connect(sender).approve(staking.address, 10000000000)
await staking.connect(sender).stake(10000000000)

await expect(swap.connect(deployer).setStaking(staking.address)).to.emit(
swap,
'SetStaking'
)

const order = await createSignedOrder({}, signer)

await expect(
Expand Down
3 changes: 1 addition & 2 deletions source/wrapper/test/Wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,7 @@ describe('Wrapper Unit Tests', () => {
PROTOCOL_FEE_LIGHT,
protocolFeeWallet.address,
REBATE_SCALE,
REBATE_MAX,
stakingToken.address
REBATE_MAX
)
await swapERC20.deployed()

Expand Down

0 comments on commit 29ea0b5

Please sign in to comment.