Skip to content

Commit

Permalink
Merge pull request #493 from bancorprotocol/add-fee-exemption-whitelist
Browse files Browse the repository at this point in the history
Add fee exemption whitelist
  • Loading branch information
ivanzhelyazkov authored Oct 18, 2024
2 parents a4188c8 + 507a74d commit 60fa652
Show file tree
Hide file tree
Showing 8 changed files with 305 additions and 119 deletions.
2 changes: 0 additions & 2 deletions contracts/helpers/TestBancorNetwork.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ contract TestBancorNetwork is BancorNetwork, TestTime {
IMasterVault initMasterVault,
IExternalProtectionVault initExternalProtectionVault,
IPoolToken initBNTPoolToken,
address bancorArbitrage,
address carbonPOL
)
BancorNetwork(
Expand All @@ -41,7 +40,6 @@ contract TestBancorNetwork is BancorNetwork, TestTime {
initMasterVault,
initExternalProtectionVault,
initBNTPoolToken,
bancorArbitrage,
carbonPOL
)
{}
Expand Down
132 changes: 103 additions & 29 deletions contracts/network/BancorNetwork.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ import {
DoesNotExist,
InvalidToken,
InvalidPool,
NotEmpty
NotEmpty,
AccessDenied
} from "../utility/Utils.sol";

import { ROLE_ASSET_MANAGER } from "../vaults/interfaces/IVault.sol";
Expand Down Expand Up @@ -119,9 +120,6 @@ contract BancorNetwork is IBancorNetwork, Upgradeable, ReentrancyGuardUpgradeabl
// the BNT pool token
IPoolToken internal immutable _bntPoolToken;

// the Bancor arbitrage contract
address internal immutable _bancorArbitrage;

// the carbon POL contract
address internal immutable _carbonPOL;

Expand Down Expand Up @@ -156,8 +154,11 @@ contract BancorNetwork is IBancorNetwork, Upgradeable, ReentrancyGuardUpgradeabl
// min network fee amount that can be burned
uint256 private _minNetworkFeeBurn;

// a set of addresses which are exempt from trading / flashloan fees
EnumerableSetUpgradeable.AddressSet private _feeExemptionWhitelist;

// upgrade forward-compatibility storage gap
uint256[MAX_GAP - 12] private __gap;
uint256[MAX_GAP - 14] private __gap;

/**
* @dev triggered when a new pool collection is added
Expand Down Expand Up @@ -236,6 +237,16 @@ contract BancorNetwork is IBancorNetwork, Upgradeable, ReentrancyGuardUpgradeabl
*/
event MinNetworkFeeBurnUpdated(uint256 oldMinNetworkFeeBurn, uint256 newMinNetworkFeeBurn);

/**
* @dev triggered when an address gets added to the fee exemption whitelist
*/
event AddressAddedToWhitelist(address indexed addr);

/**
* @dev triggered when an address gets removed from the fee exemption whitelist
*/
event AddressRemovedFromWhitelist(address indexed addr);

/**
* @dev a "virtual" constructor that is only used to set immutable state variables
*/
Expand All @@ -246,7 +257,6 @@ contract BancorNetwork is IBancorNetwork, Upgradeable, ReentrancyGuardUpgradeabl
IMasterVault initMasterVault,
IExternalProtectionVault initExternalProtectionVault,
IPoolToken initBNTPoolToken,
address bancorArbitrage,
address carbonPOL
)
validAddress(address(initBNTGovernance))
Expand All @@ -255,7 +265,6 @@ contract BancorNetwork is IBancorNetwork, Upgradeable, ReentrancyGuardUpgradeabl
validAddress(address(initMasterVault))
validAddress(address(initExternalProtectionVault))
validAddress(address(initBNTPoolToken))
validAddress(address(bancorArbitrage))
validAddress(address(carbonPOL))
{
_bntGovernance = initBNTGovernance;
Expand All @@ -267,7 +276,6 @@ contract BancorNetwork is IBancorNetwork, Upgradeable, ReentrancyGuardUpgradeabl
_masterVault = initMasterVault;
_externalProtectionVault = initExternalProtectionVault;
_bntPoolToken = initBNTPoolToken;
_bancorArbitrage = bancorArbitrage;
_carbonPOL = carbonPOL;
}

Expand Down Expand Up @@ -341,13 +349,25 @@ contract BancorNetwork is IBancorNetwork, Upgradeable, ReentrancyGuardUpgradeabl
}
}

modifier onlyWhitelisted(address addr) {
_onlyWhitelisted(addr);

_;
}

function _onlyWhitelisted(address addr) internal view {
if (!_feeExemptionWhitelist.contains(addr)) {
revert AccessDenied();
}
}

receive() external payable {}

/**
* @inheritdoc Upgradeable
*/
function version() public pure override(IVersioned, Upgradeable) returns (uint16) {
return 10;
return 11;
}

/**
Expand Down Expand Up @@ -655,7 +675,8 @@ contract BancorNetwork is IBancorNetwork, Upgradeable, ReentrancyGuardUpgradeabl
minReturnAmount,
deadline,
beneficiary,
msg.sender
msg.sender,
false
);
}

Expand All @@ -678,7 +699,8 @@ contract BancorNetwork is IBancorNetwork, Upgradeable, ReentrancyGuardUpgradeabl
maxSourceAmount,
deadline,
beneficiary,
msg.sender
msg.sender,
false
);
}

Expand All @@ -692,7 +714,7 @@ contract BancorNetwork is IBancorNetwork, Upgradeable, ReentrancyGuardUpgradeabl
uint256 minReturnAmount,
uint256 deadline,
address beneficiary
) external payable whenNotPaused only(_bancorArbitrage) returns (uint256) {
) external payable whenNotPaused onlyWhitelisted(msg.sender) returns (uint256) {
return
_tradeBySourceAmount(
sourceToken,
Expand All @@ -701,7 +723,8 @@ contract BancorNetwork is IBancorNetwork, Upgradeable, ReentrancyGuardUpgradeabl
minReturnAmount,
deadline,
beneficiary,
msg.sender
msg.sender,
true
);
}

Expand All @@ -715,7 +738,7 @@ contract BancorNetwork is IBancorNetwork, Upgradeable, ReentrancyGuardUpgradeabl
uint256 maxSourceAmount,
uint256 deadline,
address beneficiary
) external payable whenNotPaused only(_bancorArbitrage) returns (uint256) {
) external payable whenNotPaused onlyWhitelisted(msg.sender) returns (uint256) {
return
_tradeByTargetAmount(
sourceToken,
Expand All @@ -724,7 +747,8 @@ contract BancorNetwork is IBancorNetwork, Upgradeable, ReentrancyGuardUpgradeabl
maxSourceAmount,
deadline,
beneficiary,
msg.sender
msg.sender,
true
);
}

Expand All @@ -749,8 +773,8 @@ contract BancorNetwork is IBancorNetwork, Upgradeable, ReentrancyGuardUpgradeabl
}

uint256 feeAmount;
if (msg.sender == _bancorArbitrage) {
// exempt arb contract from fees
if (_feeExemptionWhitelist.contains(msg.sender)) {
// exempt from fees
feeAmount = 0;
} else {
feeAmount = MathEx.mulDivF(amount, _networkSettings.flashLoanFeePPM(token), PPM_RESOLUTION);
Expand Down Expand Up @@ -878,6 +902,51 @@ contract BancorNetwork is IBancorNetwork, Upgradeable, ReentrancyGuardUpgradeabl
_depositingEnabled = status;
}

/**
* @inheritdoc IBancorNetwork
*/
function feeExemptionWhitelist() external view returns (address[] memory) {
uint256 length = _feeExemptionWhitelist.length();
address[] memory list = new address[](length);
for (uint256 i = 0; i < length; ++i) {
list[i] = _feeExemptionWhitelist.at(i);
}
return list;
}

/**
* @dev adds an address to the fee exemption whitelist
*
* requirements:
*
* - the caller must be the admin of the contract
*/
function addToWhitelist(address addr) external onlyAdmin {
_addToWhitelist(addr);
}

/**
* @dev removes an address from the fee exemption whitelist
*
* requirements:
*
* - the caller must be the admin of the contract
*/
function removeFromWhitelist(address addr) external onlyAdmin {
if (!_feeExemptionWhitelist.remove(addr)) {
revert DoesNotExist();
}

emit AddressRemovedFromWhitelist(addr);
}

/**
* @inheritdoc IBancorNetwork
*/
function isWhitelisted(address addr) external view returns (bool) {
return _feeExemptionWhitelist.contains(addr);
}

/**
* @dev returns the POL rewards ppm
*/
Expand Down Expand Up @@ -934,6 +1003,17 @@ contract BancorNetwork is IBancorNetwork, Upgradeable, ReentrancyGuardUpgradeabl
emit MinNetworkFeeBurnUpdated(oldMinNetworkFeeBurn, newMinNetworkFeeBurn);
}

/**
* @dev adds an address to the fee exemption whitelist
*/
function _addToWhitelist(address addr) private validExternalAddress(addr) {
if (!_feeExemptionWhitelist.add(addr)) {
revert AlreadyExists();
}

emit AddressAddedToWhitelist(addr);
}

/**
* @dev generates context ID for a deposit request
*/
Expand Down Expand Up @@ -1119,13 +1199,10 @@ contract BancorNetwork is IBancorNetwork, Upgradeable, ReentrancyGuardUpgradeabl
uint256 minReturnAmount,
uint256 deadline,
address beneficiary,
address sender
address sender,
bool ignoreFees
) private returns (uint256) {
_verifyTradeParams(sourceToken, targetToken, sourceAmount, minReturnAmount, deadline);
bool _ignoreFees = false;
if (sender == _bancorArbitrage) {
_ignoreFees = true;
}

return
_trade(
Expand All @@ -1134,7 +1211,7 @@ contract BancorNetwork is IBancorNetwork, Upgradeable, ReentrancyGuardUpgradeabl
bySourceAmount: true,
amount: sourceAmount,
limit: minReturnAmount,
ignoreFees: _ignoreFees
ignoreFees: ignoreFees
}),
TraderInfo({ trader: sender, beneficiary: beneficiary }),
deadline
Expand All @@ -1151,13 +1228,10 @@ contract BancorNetwork is IBancorNetwork, Upgradeable, ReentrancyGuardUpgradeabl
uint256 maxSourceAmount,
uint256 deadline,
address beneficiary,
address sender
address sender,
bool ignoreFees
) private returns (uint256) {
_verifyTradeParams(sourceToken, targetToken, targetAmount, maxSourceAmount, deadline);
bool _ignoreFees = false;
if (sender == _bancorArbitrage) {
_ignoreFees = true;
}

return
_trade(
Expand All @@ -1166,7 +1240,7 @@ contract BancorNetwork is IBancorNetwork, Upgradeable, ReentrancyGuardUpgradeabl
bySourceAmount: false,
amount: targetAmount,
limit: maxSourceAmount,
ignoreFees: _ignoreFees
ignoreFees: ignoreFees
}),
TraderInfo({ trader: sender, beneficiary: beneficiary }),
deadline
Expand Down
14 changes: 12 additions & 2 deletions contracts/network/interfaces/IBancorNetwork.sol
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ interface IBancorNetwork is IUpgradeable {
*
* - the caller must have approved the network to transfer the source tokens on its behalf (except for in the
* native token case)
* - the caller must be the _bancorArbitrage contract
* - the caller must be in the fee exemption whitelist
*/
function tradeBySourceAmountArb(
Token sourceToken,
Expand All @@ -181,7 +181,7 @@ interface IBancorNetwork is IUpgradeable {
*
* - the caller must have approved the network to transfer the source tokens on its behalf (except for in the
* native token case)
* - the caller must be the _bancorArbitrage contract
* - the caller must be in the fee exemption whitelist
*/
function tradeByTargetAmountArb(
Token sourceToken,
Expand Down Expand Up @@ -227,4 +227,14 @@ interface IBancorNetwork is IUpgradeable {
* and disables trading on the given pool if it is not already disabled
*/
function withdrawPOL(Token pool) external returns (uint256);

/**
* @dev returns whether an address is in the fee exemption whitelist
*/
function isWhitelisted(address _address) external view returns (bool);

/**
* @dev returns the fee exemption whitelist
*/
function feeExemptionWhitelist() external view returns (address[] memory);
}
42 changes: 42 additions & 0 deletions deploy/scripts/000065-upgrade-network-v11.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { DeployedContracts, execute, InstanceName, setDeploymentMetadata, upgradeProxy } from '../../utils/Deploy';
import { DeployFunction } from 'hardhat-deploy/types';
import { HardhatRuntimeEnvironment } from 'hardhat/types';

const func: DeployFunction = async ({ getNamedAccounts }: HardhatRuntimeEnvironment) => {
const { deployer, bancorArbitrageAddress, carbonPOLAddress } = await getNamedAccounts();

// get the deployed contracts
const externalProtectionVault = await DeployedContracts.ExternalProtectionVault.deployed();
const masterVault = await DeployedContracts.MasterVault.deployed();
const networkSettings = await DeployedContracts.NetworkSettings.deployed();
const bntGovernance = await DeployedContracts.BNTGovernance.deployed();
const vbntGovernance = await DeployedContracts.VBNTGovernance.deployed();
const bnBNT = await DeployedContracts.bnBNT.deployed();

// upgrade the BancorNetwork contract
await upgradeProxy({
name: InstanceName.BancorNetwork,
args: [
bntGovernance.address,
vbntGovernance.address,
networkSettings.address,
masterVault.address,
externalProtectionVault.address,
bnBNT.address,
carbonPOLAddress
],
from: deployer
});

// add bancor arbitrage contract address to fee exemption whitelist
await execute({
name: InstanceName.BancorNetwork,
methodName: 'addToWhitelist',
args: [bancorArbitrageAddress],
from: deployer
});

return true;
};

export default setDeploymentMetadata(__filename, func);
Loading

0 comments on commit 60fa652

Please sign in to comment.