Skip to content
This repository was archived by the owner on May 9, 2024. It is now read-only.

Commit 963103b

Browse files
viatrixlastpersonP1sar
authored
Viatrix/fee handler (#519)
* WIP: Basic FeeHandler * WIP: Basic FeeHandler * Fee handler with oracle * FeeHandler: fixes after comments * Fix after review * Simplify abi decoding * Added expiration time to oracle data * sign oracle message by ethers.js * Remove prefix from signature * Add FeeCollected event * Add FeeDistributed event Co-authored-by: Oleksii Matiiasevych <lastperson@gmail.com> Co-authored-by: Kirill <pisarevkir@gmail.com>
1 parent 66ba8c4 commit 963103b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+1706
-21887
lines changed

contracts/Bridge.sol

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import "./utils/SafeCast.sol";
88
import "./interfaces/IDepositExecute.sol";
99
import "./interfaces/IERCHandler.sol";
1010
import "./interfaces/IGenericHandler.sol";
11+
import "./interfaces/IFeeHandler.sol";
1112

1213
/**
1314
@title Facilitates deposits, creation and voting of deposit proposals, and deposit executions.
@@ -21,9 +22,10 @@ contract Bridge is Pausable, AccessControl, SafeMath {
2122

2223
uint8 public _domainID;
2324
uint8 public _relayerThreshold;
24-
uint128 public _fee;
2525
uint40 public _expiry;
2626

27+
IFeeHandler public _feeHandler;
28+
2729
enum ProposalStatus {Inactive, Active, Passed, Executed, Cancelled}
2830

2931
struct Proposal {
@@ -45,6 +47,7 @@ contract Bridge is Pausable, AccessControl, SafeMath {
4547
event RelayerThresholdChanged(uint256 newThreshold);
4648
event RelayerAdded(address relayer);
4749
event RelayerRemoved(address relayer);
50+
event FeeHandlerChanged(address newFeeHandler);
4851
event Deposit(
4952
uint8 destinationDomainID,
5053
bytes32 resourceID,
@@ -125,10 +128,9 @@ contract Bridge is Pausable, AccessControl, SafeMath {
125128
@param initialRelayers Addresses that should be initially granted the relayer role.
126129
@param initialRelayerThreshold Number of votes needed for a deposit proposal to be considered passed.
127130
*/
128-
constructor (uint8 domainID, address[] memory initialRelayers, uint256 initialRelayerThreshold, uint256 fee, uint256 expiry) public {
131+
constructor (uint8 domainID, address[] memory initialRelayers, uint256 initialRelayerThreshold, uint256 expiry) public {
129132
_domainID = domainID;
130133
_relayerThreshold = initialRelayerThreshold.toUint8();
131-
_fee = fee.toUint128();
132134
_expiry = expiry.toUint40();
133135

134136
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
@@ -315,13 +317,13 @@ contract Bridge is Pausable, AccessControl, SafeMath {
315317
}
316318

317319
/**
318-
@notice Changes deposit fee.
320+
@notice Changes deposit fee handler contract address.
319321
@notice Only callable by admin.
320-
@param newFee Value {_fee} will be updated to.
322+
@param newFeeHandler Address {_feeHandler} will be updated to.
321323
*/
322-
function adminChangeFee(uint256 newFee) external onlyAdmin {
323-
require(_fee != newFee, "Current fee is equal to new fee");
324-
_fee = newFee.toUint128();
324+
function adminChangeFeeHandler(address newFeeHandler) external onlyAdmin {
325+
_feeHandler = IFeeHandler(newFeeHandler);
326+
emit FeeHandlerChanged(newFeeHandler);
325327
}
326328

327329
/**
@@ -342,25 +344,31 @@ contract Bridge is Pausable, AccessControl, SafeMath {
342344
@notice Only callable when Bridge is not paused.
343345
@param destinationDomainID ID of chain deposit will be bridged to.
344346
@param resourceID ResourceID used to find address of handler to be used for deposit.
345-
@param data Additional data to be passed to specified handler.
347+
@param depositData Additional data to be passed to specified handler.
348+
@param feeData Additional data to be passed to the fee handler.
346349
@notice Emits {Deposit} event with all necessary parameters and a handler response.
347350
- ERC20Handler: responds with an empty data.
348351
- ERC721Handler: responds with the deposited token metadata acquired by calling a tokenURI method in the token contract.
349352
- GenericHandler: responds with the raw bytes returned from the call to the target contract.
350353
*/
351-
function deposit(uint8 destinationDomainID, bytes32 resourceID, bytes calldata data) external payable whenNotPaused {
352-
require(msg.value == _fee, "Incorrect fee supplied");
354+
function deposit(uint8 destinationDomainID, bytes32 resourceID, bytes calldata depositData, bytes calldata feeData) external payable whenNotPaused {
355+
address sender = _msgSender();
356+
if (address(_feeHandler) == address(0)) {
357+
require(msg.value == 0, "no FeeHandler, msg.value != 0");
358+
} else {
359+
// Reverts on failure
360+
_feeHandler.collectFee{value: msg.value}(sender, _domainID, destinationDomainID, resourceID, depositData, feeData);
361+
}
353362

354363
address handler = _resourceIDToHandlerAddress[resourceID];
355364
require(handler != address(0), "resourceID not mapped to handler");
356365

357366
uint64 depositNonce = ++_depositCounts[destinationDomainID];
358-
address sender = _msgSender();
359367

360368
IDepositExecute depositHandler = IDepositExecute(handler);
361-
bytes memory handlerResponse = depositHandler.deposit(resourceID, sender, data);
369+
bytes memory handlerResponse = depositHandler.deposit(resourceID, sender, depositData);
362370

363-
emit Deposit(destinationDomainID, resourceID, depositNonce, sender, data, handlerResponse);
371+
emit Deposit(destinationDomainID, resourceID, depositNonce, sender, depositData, handlerResponse);
364372
}
365373

366374
/**
@@ -489,16 +497,4 @@ contract Bridge is Pausable, AccessControl, SafeMath {
489497

490498
emit ProposalEvent(domainID, depositNonce, ProposalStatus.Executed, dataHash);
491499
}
492-
493-
/**
494-
@notice Transfers eth in the contract to the specified addresses. The parameters addrs and amounts are mapped 1-1.
495-
This means that the address at index 0 for addrs will receive the amount (in WEI) from amounts at index 0.
496-
@param addrs Array of addresses to transfer {amounts} to.
497-
@param amounts Array of amonuts to transfer to {addrs}.
498-
*/
499-
function transferFunds(address payable[] calldata addrs, uint[] calldata amounts) external onlyAdmin {
500-
for (uint256 i = 0; i < addrs.length; i++) {
501-
addrs[i].transfer(amounts[i]);
502-
}
503-
}
504500
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// SPDX-License-Identifier: LGPL-3.0-only
2+
pragma solidity 0.8.11;
3+
pragma experimental ABIEncoderV2;
4+
5+
import "../../interfaces/IFeeHandler.sol";
6+
import "../../utils/AccessControl.sol";
7+
8+
/**
9+
@title Handles deposit fees.
10+
@author ChainSafe Systems.
11+
@notice This contract is intended to be used with the Bridge contract.
12+
*/
13+
contract BasicFeeHandler is IFeeHandler, AccessControl {
14+
address public immutable _bridgeAddress;
15+
16+
uint256 public _fee;
17+
18+
event FeeChanged(
19+
uint256 newFee
20+
);
21+
22+
modifier onlyBridge() {
23+
_onlyBridge();
24+
_;
25+
}
26+
27+
function _onlyBridge() private view {
28+
require(msg.sender == _bridgeAddress, "sender must be bridge contract");
29+
}
30+
31+
/**
32+
@param bridgeAddress Contract address of previously deployed Bridge.
33+
*/
34+
constructor(address bridgeAddress) public {
35+
_bridgeAddress = bridgeAddress;
36+
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
37+
}
38+
39+
/**
40+
@notice Collects fee for deposit.
41+
@param sender Sender of the deposit.
42+
@param destinationDomainID ID of chain deposit will be bridged to.
43+
@param resourceID ResourceID to be used when making deposits.
44+
@param depositData Additional data to be passed to specified handler.
45+
@param feeData Additional data to be passed to the fee handler.
46+
*/
47+
function collectFee(address sender, uint8 fromDomainID, uint8 destinationDomainID, bytes32 resourceID, bytes calldata depositData, bytes calldata feeData) payable external onlyBridge {
48+
require(msg.value == _fee, "Incorrect fee supplied");
49+
emit FeeCollected(sender, fromDomainID, destinationDomainID, resourceID, _fee, address(0));
50+
}
51+
52+
/**
53+
@notice Calculates fee for deposit.
54+
@param sender Sender of the deposit.
55+
@param destinationDomainID ID of chain deposit will be bridged to.
56+
@param resourceID ResourceID to be used when making deposits.
57+
@param depositData Additional data to be passed to specified handler.
58+
@param feeData Additional data to be passed to the fee handler.
59+
@return Returns the fee amount.
60+
*/
61+
function calculateFee(address sender, uint8 fromDomainID, uint8 destinationDomainID, bytes32 resourceID, bytes calldata depositData, bytes calldata feeData) external view returns(uint256, address) {
62+
return (_fee, address(0));
63+
}
64+
65+
/**
66+
@notice Sets new value of the fee.
67+
@notice Only callable by admin.
68+
@param newFee Value {_fee} will be updated to.
69+
*/
70+
function changeFee(uint256 newFee) external onlyAdmin {
71+
require(_fee != newFee, "Current fee is equal to new fee");
72+
_fee = newFee;
73+
emit FeeChanged(newFee);
74+
}
75+
76+
/**
77+
@notice Transfers eth in the contract to the specified addresses. The parameters addrs and amounts are mapped 1-1.
78+
This means that the address at index 0 for addrs will receive the amount (in WEI) from amounts at index 0.
79+
@param addrs Array of addresses to transfer {amounts} to.
80+
@param amounts Array of amonuts to transfer to {addrs}.
81+
*/
82+
function transferFee(address payable[] calldata addrs, uint[] calldata amounts) external onlyAdmin {
83+
require(addrs.length == amounts.length, "addrs[], amounts[]: diff length");
84+
for (uint256 i = 0; i < addrs.length; i++) {
85+
(bool success,) = addrs[i].call{value: amounts[i]}("");
86+
require(success, "Fee ether transfer failed");
87+
emit FeeDistributed(address(0), addrs[i], amounts[i]);
88+
}
89+
}
90+
91+
modifier onlyAdmin() {
92+
require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "sender doesn't have admin role");
93+
_;
94+
}
95+
}

0 commit comments

Comments
 (0)