Skip to content

Commit

Permalink
feat(collector): add multitoken support)
Browse files Browse the repository at this point in the history
  • Loading branch information
jurajpiar committed Feb 9, 2023
1 parent b13d1a1 commit 7f3a5cc
Show file tree
Hide file tree
Showing 3 changed files with 550 additions and 3 deletions.
138 changes: 138 additions & 0 deletions contracts/MultitokenCollector.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
// SPDX-License-Identifier:MIT
pragma solidity ^0.6.12;
pragma experimental ABIEncoderV2;

import "./interfaces/ICollector.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";

contract MultitokenCollector is ICollector {
address private _remainderAddress;
RevenuePartner[] private _partners;
IERC20[] private _tokens;
address public owner;

modifier onlyOwner() {
require(msg.sender == owner, "Only owner can call this");
_;
}

modifier noBalanceToShare() {
for (uint256 i = 0; i < _tokens.length; i++) {
require(
_tokens[i].balanceOf(address(this)) < _partners.length,
"There is balance to share"
);
}
_;
}

modifier updateValidShares(RevenuePartner[] memory partners) {
_;
uint256 totalShares;
for (uint256 i = 0; i < partners.length; i++) {
require(partners[i].share > 0, "0 is not a valid share");
totalShares = totalShares + partners[i].share;
_partners.push(partners[i]);
}
require(totalShares == 100, "Shares must add up to 100%");
}

constructor(
address _owner,
IERC20[] memory tokens,
RevenuePartner[] memory partners,
address remainderAddress
) public updateValidShares(partners) {
owner = _owner;
_remainderAddress = remainderAddress;

for (uint i = 0; i < tokens.length; i++) {
_tokens.push(tokens[i]);
}
}

function getPartners() external view returns (RevenuePartner[] memory) {
return _partners;
}

function updateShares(
RevenuePartner[] memory partners
) external onlyOwner noBalanceToShare updateValidShares(partners) {
delete _partners;
}

//@notice Withdraw the actual remainder and then update the remainder's address
//for a new one. This function is the only way to withdraw the remainder.
function updateRemainderAddress(
address remainderAddress
) external onlyOwner noBalanceToShare {
for (uint256 i = 0; i < _tokens.length; i++) {
IERC20 token = _tokens[i];
uint256 balance = token.balanceOf(address(this));

if (balance != 0) {
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory ret) = address(token).call{
gas: 200000
}(
abi.encodeWithSelector(
hex"a9059cbb",
_remainderAddress,
balance
)
);

require(
success && (ret.length == 0 || abi.decode(ret, (bool))),
"Unable to transfer remainder"
);
}
}

// solhint-disable-next-line
_remainderAddress = remainderAddress;
}

function getTokens() external view returns (IERC20[] memory) {
return _tokens;
}

function getRemainderAddress() external view returns (address) {
return _remainderAddress;
}

function withdrawToken(IERC20 token) public onlyOwner {
uint256 balance = token.balanceOf(address(this));
require(balance >= _partners.length, "Not enough balance to split");

address tokenAddr = address(token);

for (uint256 i = 0; i < _partners.length; i++) {
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory ret) = tokenAddr.call(
abi.encodeWithSelector(
hex"a9059cbb",
_partners[i].beneficiary,
SafeMath.div(SafeMath.mul(balance, _partners[i].share), 100)
)
);

require(
success && (ret.length == 0 || abi.decode(ret, (bool))),
"Unable to withdraw"
);
}
}

function withdraw() external override onlyOwner {
for (uint256 i = 0; i < _tokens.length; i++) {
withdrawToken(_tokens[i]);
}
}

function transferOwnership(address _owner) external override onlyOwner {
require(_owner != address(0), "Owner cannot be zero address");
owner = _owner;
}
}
6 changes: 3 additions & 3 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ const config: HardhatUserConfig = {
},
tdd: {
tasks: [
// 'clean',
// { command: 'compile', params: { quiet: true } },
'clean',
{ command: 'compile', params: { quiet: true } },
{
command: 'test',
params: {
Expand All @@ -89,7 +89,7 @@ const config: HardhatUserConfig = {
},
},
],
files: ['./test/**/*.ts'],
files: ['./test/**/*.ts', './contracts/*.sol'],
verbose: true,
clearOnStart: true,
},
Expand Down
Loading

0 comments on commit 7f3a5cc

Please sign in to comment.