Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions contracts/periphery/crons/ZaiFeeCollectorCronAerodrome.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// SPDX-License-Identifier: GPL-3.0

// ███╗ ███╗ █████╗ ██╗ ██╗ █████╗
// ████╗ ████║██╔══██╗██║ ██║██╔══██╗
// ██╔████╔██║███████║███████║███████║
// ██║╚██╔╝██║██╔══██║██╔══██║██╔══██║
// ██║ ╚═╝ ██║██║ ██║██║ ██║██║ ██║
// ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝

// Website: https://maha.xyz
// Discord: https://discord.gg/mahadao
// Twitter: https://twitter.com/mahaxyz_

pragma solidity 0.8.21;

import {IMultiStakingRewardsERC4626} from "../../interfaces/core/IMultiStakingRewardsERC4626.sol";
import {ZaiFeeCollectorCronBase} from "./ZaiFeeCollectorCronBase.sol";

/// @title Fee collector cron job for Zai on Base
/// @author maha.xyz
/// @notice On base we give 60% of our revenue to aerodrome voters and 40% to the treasury
contract ZaiFeeCollectorCronAerodrome is ZaiFeeCollectorCronBase {
IMultiStakingRewardsERC4626 public safetyPoolZai;
IMultiStakingRewardsERC4626 public stakerMahaZai;
IMultiStakingRewardsERC4626 public stakerUsdcZai;

address public treasury;
address public aerodromeBribe;
address public connextBridge;

function init(
address _rewardToken,
address _weth,
address _odos,
address[] memory _tokens,
address _gelatoooooo,
address _stakerMahaZai,
address _stakerUsdcZai,
address _safetyPoolZai,
address _governance
) public reinitializer(1) {
__ZaiFeeCollectorCronBase_init(_rewardToken, _weth, _odos, _tokens, _gelatoooooo, _governance);

safetyPoolZai = IMultiStakingRewardsERC4626(_safetyPoolZai);
stakerMahaZai = IMultiStakingRewardsERC4626(_stakerMahaZai);
stakerUsdcZai = IMultiStakingRewardsERC4626(_stakerUsdcZai);

rewardToken.approve(_stakerMahaZai, type(uint256).max);
rewardToken.approve(_stakerUsdcZai, type(uint256).max);
rewardToken.approve(_safetyPoolZai, type(uint256).max);
}

function swap(bytes memory data) public {
require(msg.sender == owner() || msg.sender == gelatoooooo, "who dis?");

// swap on odos
(bool success,) = odos.call(data);
require(success, "odos call failed");

// send all rewardToken to the destination
uint256 amt = rewardToken.balanceOf(address(this));

uint256 aerodromeAmt = amt * 3 / 5; // give 60% to the treasury
uint256 zaiMainnetBridgeAmt = amt - aerodromeAmt; // send the rest back to mainnet treasury

// todo send the usdc back via connext to mainnet
// todo send the usdc as rewards directly to aerodrome

// emit events
emit RevenueCollected(amt);
emit RevenueDistributed(aerodromeBribe, aerodromeAmt);
emit RevenueDistributed(address(stakerMahaZai), zaiMainnetBridgeAmt);
}
}
80 changes: 80 additions & 0 deletions contracts/periphery/crons/ZaiFeeCollectorCronBase.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// SPDX-License-Identifier: GPL-3.0

// ███╗ ███╗ █████╗ ██╗ ██╗ █████╗
// ████╗ ████║██╔══██╗██║ ██║██╔══██╗
// ██╔████╔██║███████║███████║███████║
// ██║╚██╔╝██║██╔══██║██╔══██║██╔══██║
// ██║ ╚═╝ ██║██║ ██║██║ ██║██║ ██║
// ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝

// Website: https://maha.xyz
// Discord: https://discord.gg/mahadao
// Twitter: https://twitter.com/mahaxyz_

pragma solidity 0.8.21;

import {IWETH} from "../../interfaces/governance/IWETH.sol";
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {IERC20} from "@openzeppelin/contracts/interfaces/IERC20.sol";

abstract contract ZaiFeeCollectorCronBase is OwnableUpgradeable {
address public gelatoooooo;
address public odos;
address[] public tokens;
IERC20 public rewardToken;
IWETH public weth;

event EthCollected(uint256 indexed amount);
event RevenueCollected(uint256 indexed amount);
event RevenueDistributed(address indexed to, uint256 indexed amount);

function __ZaiFeeCollectorCronBase_init(
address _rewardToken,
address _weth,
address _odos,
address[] memory _tokens,
address _gelatoooooo,
address _governance
) internal onlyInitializing {
__Ownable_init(msg.sender);

weth = IWETH(_weth);
rewardToken = IERC20(_rewardToken);
gelatoooooo = _gelatoooooo;

setTokens(_tokens);
setOdos(_odos);

_transferOwnership(_governance);
}

receive() external payable {
weth.deposit{value: msg.value}();
emit EthCollected(msg.value);
}

function setOdos(address _odos) public onlyOwner {
odos = _odos;
}

function balances() public view returns (uint256[] memory, address[] memory) {
uint256[] memory amounts = new uint256[](tokens.length);

for (uint256 i = 0; i < tokens.length; i++) {
amounts[i] = IERC20(tokens[i]).balanceOf(address(this));
}

return (amounts, tokens);
}

function setTokens(address[] memory _tokens) public onlyOwner {
tokens = _tokens;
for (uint256 i = 0; i < tokens.length; i++) {
IERC20(tokens[i]).approve(odos, type(uint256).max);
}
}

function refund(IERC20 token) public onlyOwner {
token.transfer(msg.sender, token.balanceOf(address(this)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,17 @@
pragma solidity 0.8.21;

import {IMultiStakingRewardsERC4626} from "../../interfaces/core/IMultiStakingRewardsERC4626.sol";
import {IWETH} from "../../interfaces/governance/IWETH.sol";
import {ZaiFeeCollectorCronBase} from "./ZaiFeeCollectorCronBase.sol";

import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {IERC20} from "@openzeppelin/contracts/interfaces/IERC20.sol";

contract ZaiFeeCollectorCron is OwnableUpgradeable {
contract ZaiFeeCollectorCronMainnet is ZaiFeeCollectorCronBase {
address public collector;
address public gelatoooooo;
address public odos;
address[] public tokens;

IMultiStakingRewardsERC4626 public safetyPoolZai;
IMultiStakingRewardsERC4626 public stakerMahaZai;
IMultiStakingRewardsERC4626 public stakerUsdcZai;

IWETH public weth;
IERC20 public rewardToken;
address public treasury;

event RevenueCollected(uint256 indexed amount);
event EthCollected(uint256 indexed amount);
event RevenueDistributed(address indexed to, uint256 indexed amount);

function init(
address _rewardToken,
address _weth,
Expand All @@ -49,53 +36,15 @@ contract ZaiFeeCollectorCron is OwnableUpgradeable {
address _safetyPoolZai,
address _governance
) public reinitializer(1) {
__Ownable_init(msg.sender);
__ZaiFeeCollectorCronBase_init(_rewardToken, _weth, _odos, _tokens, _gelatoooooo, _governance);

weth = IWETH(_weth);
rewardToken = IERC20(_rewardToken);
gelatoooooo = _gelatoooooo;
safetyPoolZai = IMultiStakingRewardsERC4626(_safetyPoolZai);
stakerMahaZai = IMultiStakingRewardsERC4626(_stakerMahaZai);
stakerUsdcZai = IMultiStakingRewardsERC4626(_stakerUsdcZai);

setTokens(_tokens);
setOdos(_odos);

rewardToken.approve(_stakerMahaZai, type(uint256).max);
rewardToken.approve(_stakerUsdcZai, type(uint256).max);
rewardToken.approve(_safetyPoolZai, type(uint256).max);

_transferOwnership(_governance);
}

receive() external payable {
weth.deposit{value: msg.value}();
emit EthCollected(msg.value);
}

function setOdos(address _odos) public onlyOwner {
odos = _odos;
}

function balances() public view returns (uint256[] memory, address[] memory) {
uint256[] memory amounts = new uint256[](tokens.length);

for (uint256 i = 0; i < tokens.length; i++) {
amounts[i] = IERC20(tokens[i]).balanceOf(address(this));
}

return (amounts, tokens);
}

function setTokens(address[] memory _tokens) public onlyOwner {
tokens = _tokens;
approve();
}

function approve() public {
for (uint256 i = 0; i < tokens.length; i++) {
IERC20(tokens[i]).approve(odos, type(uint256).max);
}
}

function swap(bytes memory data) public {
Expand Down Expand Up @@ -125,8 +74,4 @@ contract ZaiFeeCollectorCron is OwnableUpgradeable {
emit RevenueDistributed(address(safetyPoolZai), zaiSafetyPoolAmt);
emit RevenueDistributed(address(stakerUsdcZai), zaiUsdcAmt);
}

function refund(IERC20 token) public onlyOwner {
token.transfer(msg.sender, token.balanceOf(address(this)));
}
}