Skip to content

Commit

Permalink
Merge pull request #48 from 1inch/feat/add-operators
Browse files Browse the repository at this point in the history
support operators
  • Loading branch information
ZumZoom authored Feb 14, 2025
2 parents 5d64ac8 + 0ae631a commit a5d06d0
Show file tree
Hide file tree
Showing 5 changed files with 275 additions and 58 deletions.
17 changes: 15 additions & 2 deletions contracts/FeeCollector.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ contract FeeCollector is BalanceManager {
address private immutable _OWNER;
address private immutable _LIMIT_ORDER_PROTOCOL;

address public operator;

event OperatorChanged(address newOperator);

error AccessDenied();

constructor(IWETH weth, address lop, address owner) BalanceManager(weth) {
if (owner == address(0) || lop == address(0)) revert ZeroAddress();

Expand All @@ -19,10 +25,17 @@ contract FeeCollector is BalanceManager {
}

modifier onlyOwner() override {
if(msg.sender != _OWNER) revert OnlyOwner();
if (msg.sender != operator) revert OnlyOwner();
_;
}

function setOperator(address newOperator) external {
if (msg.sender != _OWNER) revert AccessDenied();

operator = newOperator;
emit OperatorChanged(newOperator);
}

function isValidSignature(bytes32 hash, bytes calldata signature) external view override returns (bytes4 magicValue) {
address signer;
if (msg.sender == _LIMIT_ORDER_PROTOCOL) {
Expand All @@ -31,7 +44,7 @@ contract FeeCollector is BalanceManager {
signer = ECDSA.recover(keccak256(abi.encodePacked(hash, address(this))), signature);
}

if (signer == _OWNER) magicValue = this.isValidSignature.selector;
if (signer == operator) magicValue = this.isValidSignature.selector;
}

function _targetToCheck() internal view override returns(address) {
Expand Down
46 changes: 46 additions & 0 deletions deploy/upgrade-fee-collector-zksync.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const hre = require('hardhat');
const { getChainId, ethers } = hre;

const WETH = {
324: '0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91', // zksync
31337: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // Hardhat
};

const FEE_COLLECTOR_FACTORY = '0x0a479E2ac6d90e15d3c1Fae861b84260D7D4fadb';

const LOP = '0x6fd4383cB451173D5f9304F041C7BCBf27d561fF';

const FEE_COLLECTOR_OWNER = {
324: '0x5cEf041D1C3198Ce7F9D5E0521867e670da7520e', // zksync
31337: '0x9F8102b1bB05785BaD2874f2C7B1aaea4c6D976a', // hardhat
};

module.exports = async ({ getNamedAccounts, deployments }) => {
console.log('running deploy script');
const chainId = await getChainId();
console.log('network id ', chainId);

const { deployer } = await getNamedAccounts();
const { deploy } = deployments;

const feeCollector = await deploy('FeeCollector', { args: [WETH[chainId], LOP, FEE_COLLECTOR_OWNER[chainId]], from: deployer });

console.log(`FeeCollector impl deployed to: ${feeCollector.address}`);

if (await getChainId() !== '31337') {
await hre.run('verify:verify', {
address: feeCollector.address,
constructorArguments: [WETH[chainId], LOP, FEE_COLLECTOR_OWNER[chainId]],
});
}

const feeCollectorFactory = await ethers.getContractAt('FeeCollectorFactory', FEE_COLLECTOR_FACTORY);

console.log(
'upgradeTo is required: %s .upgradeTo(%s)',
feeCollectorFactory.target,
feeCollector.address,
);
};

module.exports.skip = async () => true;
98 changes: 98 additions & 0 deletions deploy/upgrade-fee-collector.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
const hre = require('hardhat');
const { getChainId, ethers } = hre;

const WETH = {
1: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // Mainnet
56: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', // BSC
137: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270', // Matic
42161: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1', // Arbitrum
10: '0x4200000000000000000000000000000000000006', // Optimistic
43114: '0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7', // Avalanche
100: '0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d', // xDAI
250: '0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83', // FTM
1313161554: '0xC9BdeEd33CD01541e1eeD10f90519d2C06Fe3feB', // Aurora
8217: '0xe4f05A66Ec68B54A58B17c22107b02e0232cC817', // Klaytn
8453: '0x4200000000000000000000000000000000000006', // Base
59144: '0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f', // Linea
31337: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // Hardhat
};

const FEE_COLLECTOR_OWNER = {
1: '0x9F8102b1bB05785BaD2874f2C7B1aaea4c6D976a', // Mainnet
56: '0x7a4C2f97069f874A355607eBC52aEfCc4eAc9202', // BSC
137: '0xA154B43EEa8905Ef684995424fF476656ab50A61', // Matic
42161: '0x0f6E3fB5D73AFd2e594AC4b962E57E603E650875', // Arbitrum
10: '0x5B18c756F4D9B54255a17BF120da2cF74743247f', // Optimistic
43114: '0x3b26f6325868Ddd8CB223Ac766cE02a2906653A5', // Avalanche
100: '0x9e05fA5A389D782C17369a76d8e59A268973275F', // xDAI
250: '0x0dBa0Da8C5642Db20fEAc06b7A6E9e08e6E501C6', // FTM
1313161554: '0x0e9292Ff8be5bA8075bE05F5F155E10422AE8017', // Aurora
8217: '0xa38038f9Ac2b3A7b4247804A46C787960E160Aed', // Klaytn (not safe)
8453: '0xa4659995DC39d891C1bA9131Aaf5F000E5B57224', // Base
59144: '0x9cCf4d6B76976Ab11CF9f9219A38BA28983A9a27', // Linea
31337: '0x9F8102b1bB05785BaD2874f2C7B1aaea4c6D976a', // Hardhat
};

const LOP = '0x111111125421cA6dc452d289314280a0f8842A65';
const CREATE3_DEPLOYER_CONTRACT = '0x65B3Db8bAeF0215A1F9B14c506D2a3078b2C84AE';

const FEE_COLLECTOR_SALT = ethers.keccak256(ethers.toUtf8Bytes('FeeCollector_v2'));
const FEE_COLLECTOR_FACTORY_SALT = ethers.keccak256(ethers.toUtf8Bytes('FeeCollectorFactory'));

const FEE_COLLECTOR_TYPES = ['Safe', 'DevPortal'];

const SALTS = FEE_COLLECTOR_TYPES.reduce((o, key) => ({ ...o, [key]: ethers.keccak256(ethers.toUtf8Bytes(key)) }), {});

const OPERATORS = {
Safe: '0x0829b195d2d53887cd2316c0acb390ef8fecaef9',
DevPortal: '0xA98F85F55F259ef41548251c93409F1D60e804e4',
};

module.exports = async () => {
console.log('running deploy script');
const chainId = await getChainId();
console.log('network id ', chainId);

const create3Deployer = await ethers.getContractAt('ICreate3Deployer', CREATE3_DEPLOYER_CONTRACT);

const FeeCollector = await ethers.getContractFactory('FeeCollector');

const implDeployData = (await FeeCollector.getDeployTransaction(
WETH[chainId],
LOP,
FEE_COLLECTOR_OWNER[chainId],
)).data;

const implDeployTxn = await create3Deployer.deploy(FEE_COLLECTOR_SALT, implDeployData);
await implDeployTxn.wait();

console.log(`FeeCollector impl deployed to: ${await create3Deployer.addressOf(FEE_COLLECTOR_SALT)}`);

if (await getChainId() !== '31337') {
await hre.run('verify:verify', {
address: await create3Deployer.addressOf(FEE_COLLECTOR_SALT),
constructorArguments: [WETH[chainId], LOP, FEE_COLLECTOR_OWNER[chainId]],
});
}

const feeCollectorFactory = await ethers.getContractAt('FeeCollectorFactory', await create3Deployer.addressOf(FEE_COLLECTOR_FACTORY_SALT));

console.log(
'upgradeTo is required: %s .upgradeTo(%s)',
feeCollectorFactory.target,
await create3Deployer.addressOf(FEE_COLLECTOR_SALT),
);

for (const fcType of FEE_COLLECTOR_TYPES) {
const fc = await feeCollectorFactory.getFeeCollectorAddress(SALTS[fcType]);

console.log(
'setOperator for "%s" is required: %s .setOperator(%s)',
fcType,
fc,
OPERATORS[fcType],
);
}
};

module.exports.skip = async () => true;
171 changes: 115 additions & 56 deletions deployments/zksync/FeeCollector.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions test/FeeCollector.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ describe('FeeCollector', function () {

const feeCollector = await (await ethers.getContractFactory('FeeCollector')).attach(feeCollectorAddr);

await feeCollector.setOperator(alice);
await feeCollector.rescueEther();

expect(await ethers.provider.getBalance(feeCollectorAddr)).to.eq(0n);
Expand Down

0 comments on commit a5d06d0

Please sign in to comment.