Skip to content

Commit

Permalink
refactor: change some comments in the code and deployment scripts rea…
Browse files Browse the repository at this point in the history
…dy (#15)

* refactor: change some comments in the code and deployment scripts ready

* changing core
  • Loading branch information
sogipec authored Feb 21, 2023
1 parent 33e7271 commit d8ba1f1
Show file tree
Hide file tree
Showing 16 changed files with 173 additions and 144 deletions.
54 changes: 28 additions & 26 deletions contracts/DistributionCreator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,9 @@ import "./struct/RewardTokenAmounts.sol";

/// @title DistributionCreator
/// @author Angle Labs, Inc.
/// @notice Manages the distribution of rewards across different UniswapV3 pools
/// @dev This contract is mostly a helper for APIs getting built on top and helping in Angle
/// UniswapV3 incentivization scheme
/// @dev People depositing rewards should have signed a `message` with the conditions for using the
/// @notice Manages the distribution of rewards across different pools with concentrated liquidity (like on Uniswap V3)
/// @dev This contract is mostly a helper for APIs built on top of Merkl
/// @dev People depositing rewards must have signed a `message` with the conditions for using the
/// product
contract DistributionCreator is UUPSHelper, ReentrancyGuardUpgradeable {
using SafeERC20 for IERC20;
Expand All @@ -64,13 +63,13 @@ contract DistributionCreator is UUPSHelper, ReentrancyGuardUpgradeable {
/// @notice Base for fee computation
uint256 public constant BASE_9 = 1e9;

/// @notice `CoreBorrow` contract handling access control
ICoreBorrow public coreBorrow;
/// @notice `Core` contract handling access control
ICore public core;

/// @notice User contract for distributing rewards
address public distributor;

/// @notice Address to which fees will be forwarded
/// @notice Address to which fees are forwarded
address public feeRecipient;

/// @notice Value (in base 10**9) of the fees taken when creating a distribution for a pool which do not
Expand Down Expand Up @@ -113,7 +112,7 @@ contract DistributionCreator is UUPSHelper, ReentrancyGuardUpgradeable {

uint256[36] private __gap;

// ============================== ERRORS / EVENTS ==============================
// =================================== EVENTS ==================================

event DistributorUpdated(address indexed _distributor);
event FeeRebateUpdated(address indexed user, uint256 userFeeRebate);
Expand All @@ -126,11 +125,11 @@ contract DistributionCreator is UUPSHelper, ReentrancyGuardUpgradeable {
event UserSigned(bytes32 messageHash, address indexed user);
event UserSigningWhitelistToggled(address indexed user, uint256 toggleStatus);

// ================================== MODIFIER =================================
// ================================= MODIFIERS =================================

/// @notice Checks whether the `msg.sender` has the governor role or the guardian role
modifier onlyGovernorOrGuardian() {
if (!coreBorrow.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();
if (!core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();
_;
}

Expand All @@ -143,31 +142,34 @@ contract DistributionCreator is UUPSHelper, ReentrancyGuardUpgradeable {
// ================================ CONSTRUCTOR ================================

function initialize(
ICoreBorrow _coreBorrow,
ICore _core,
address _distributor,
uint256 _fees
) external initializer {
if (address(_coreBorrow) == address(0) || _distributor == address(0)) revert ZeroAddress();
if (address(_core) == address(0) || _distributor == address(0)) revert ZeroAddress();
if (_fees > BASE_9) revert InvalidParam();
distributor = _distributor;
coreBorrow = _coreBorrow;
core = _core;
fees = _fees;
}

constructor() initializer {}

/// @inheritdoc UUPSUpgradeable
function _authorizeUpgrade(address) internal view override onlyGuardianUpgrader(coreBorrow) {}
function _authorizeUpgrade(address) internal view override onlyGuardianUpgrader(core) {}

// ============================== DEPOSIT FUNCTION =============================

/// @notice Creates a `distribution` to incentivize a given UniswapV3 pool for a specific period of time
/// @notice Creates a `distribution` to incentivize a given pool for a specific period of time
/// @return distributionAmount How many reward tokens are actually taken into consideration in the contract
/// @dev It's important to make sure that the address specified as a UniV3 pool is effectively a pool
/// otherwise they will not be handled by the distribution script and rewards may be lost
/// @dev If the address specified as a UniV3 pool is not effectively a pool, it will not be handled by the
/// distribution script and rewards may be lost
/// @dev Reward tokens sent as part of distributions must have been whitelisted before and amounts
/// sent should be bigger than a minimum amount specific to each token
/// @dev The `positionWrappers` specified in the `distribution` struct need to be supported by the script
/// @dev If the pool incentivized contains agEUR, then no fees are taken on the rewards
/// @dev This function will revert if the user has not signed the message `messageHash` once through one of
/// List of supported `positionWrappers` can be found in the docs.
/// @dev If the pool incentivized contains one whitelisted token, then no fees are taken on the rewards
/// @dev This function reverts if the sender has not signed the message `messageHash` once through one of
/// the functions enabling to sign
function createDistribution(DistributionParameters memory distribution)
external
Expand Down Expand Up @@ -196,7 +198,7 @@ contract DistributionCreator is UUPSHelper, ReentrancyGuardUpgradeable {
}

/// @notice Checks whether the `msg.sender`'s `signature` is compatible with the message
/// to sign and stores the fact that signing was done
/// to sign and stores the signature
/// @dev If you signed the message once, and the message has not been modified, then you do not
/// need to sign again
function sign(bytes calldata signature) external {
Expand All @@ -221,9 +223,9 @@ contract DistributionCreator is UUPSHelper, ReentrancyGuardUpgradeable {
uint32 epochStart = _getRoundedEpoch(distribution.epochStart);
uint256 minDistributionAmount = rewardTokenMinAmounts[distribution.rewardToken];
distribution.epochStart = epochStart;
// Reward will not be accepted in the following conditions:
// Reward are not accepted in the following conditions:
if (
// if epoch parameters would lead to a past distribution
// if epoch parameters lead to a past distribution
epochStart + EPOCH_DURATION < block.timestamp ||
// if the amount of epochs for which this distribution should last is zero
distribution.numEpoch == 0 ||
Expand Down Expand Up @@ -278,12 +280,12 @@ contract DistributionCreator is UUPSHelper, ReentrancyGuardUpgradeable {
// ================================= UI HELPERS ================================
// These functions are not to be queried on-chain and hence are not optimized for gas consumption

/// @notice Returns the list of all distributions ever distributed or to be distributed
/// @notice Returns the list of all distributions ever made or to be done in the future
function getAllDistributions() external view returns (DistributionParameters[] memory) {
return distributionList;
}

/// @notice Returns the list of all currently active distributions on UniswapV3 pool
/// @notice Returns the list of all currently active distributions on pools of supported AMMs (like Uniswap V3)
function getActiveDistributions() external view returns (ExtensiveDistributionParameters[] memory) {
uint32 roundedEpoch = _getRoundedEpoch(uint32(block.timestamp));
return _getPoolDistributionsBetweenEpochs(address(0), roundedEpoch, roundedEpoch + EPOCH_DURATION);
Expand Down Expand Up @@ -323,8 +325,8 @@ contract DistributionCreator is UUPSHelper, ReentrancyGuardUpgradeable {
}

/// @notice Gets the distributions that were or will be live at some point between `epochStart` (included) and `epochEnd` (excluded)
/// @dev If a distribution starts during `epochEnd`, it will not be returned by this function
/// @dev Conversely, if a distribution starts after `epochStart` and ends before `epochEnd`, it will be returned by this function
/// @dev If a distribution starts during `epochEnd`, it is not be returned by this function
/// @dev Conversely, if a distribution starts after `epochStart` and ends before `epochEnd`, it is returned by this function
function getDistributionsBetweenEpochs(uint32 epochStart, uint32 epochEnd)
external
view
Expand Down
29 changes: 13 additions & 16 deletions contracts/Distributor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ import "@openzeppelin/contracts/utils/math/SafeCast.sol";
import "./utils/UUPSHelper.sol";

struct MerkleTree {
// Root of a Merkle tree which leaves are (address user, address token, uint amount)
// representing an amount of tokens owed to user.
// Root of a Merkle tree which leaves are `(address user, address token, uint amount)`
// representing an amount of tokens accumulated by `user`.
// The Merkle tree is assumed to have only increasing amounts: that is to say if a user can claim 1,
// then after the amount associated in the Merkle tree for this token should be x > 1
bytes32 merkleRoot;
Expand All @@ -57,11 +57,8 @@ struct Claim {
}

/// @title Distributor
/// @notice Allows AMMs LPs to claim the rewards that were distributed to them
/// @notice Allows LPs on AMMs with concentrated liquidity to claim the rewards that were distributed to them
/// @author Angle Labs. Inc
/// @dev This contract relies on whitelisted or Angle-governance controlled addresses to update the Merkle root
/// for reward distribution. After each tree update, there is a dispute period, during which it is possible to
/// fallback to the old version of the Merkle root
contract Distributor is UUPSHelper {
using SafeERC20 for IERC20;

Expand All @@ -76,8 +73,8 @@ contract Distributor is UUPSHelper {
/// @notice Token to deposit to freeze the roots update
IERC20 public disputeToken;

/// @notice `CoreBorrow` contract handling access control
ICoreBorrow public coreBorrow;
/// @notice `Core` contract handling access control
ICore public core;

/// @notice Address which created the dispute
/// @dev Used to store if there is an ongoing dispute
Expand Down Expand Up @@ -124,13 +121,13 @@ contract Distributor is UUPSHelper {

/// @notice Checks whether the `msg.sender` has the governor role or the guardian role
modifier onlyGovernorOrGuardian() {
if (!coreBorrow.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();
if (!core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();
_;
}

/// @notice Checks whether the `msg.sender` is the `user` address or is a trusted address
modifier onlyTrustedOrUser(address user) {
if (user != msg.sender && canUpdateMerkleRoot[msg.sender] != 1 && !coreBorrow.isGovernorOrGuardian(msg.sender))
if (user != msg.sender && canUpdateMerkleRoot[msg.sender] != 1 && !core.isGovernorOrGuardian(msg.sender))
revert NotTrusted();
_;
}
Expand All @@ -139,13 +136,13 @@ contract Distributor is UUPSHelper {

constructor() initializer {}

function initialize(ICoreBorrow _coreBorrow) external initializer {
if (address(_coreBorrow) == address(0)) revert ZeroAddress();
coreBorrow = _coreBorrow;
function initialize(ICore _core) external initializer {
if (address(_core) == address(0)) revert ZeroAddress();
core = _core;
}

/// @inheritdoc UUPSUpgradeable
function _authorizeUpgrade(address) internal view override onlyGuardianUpgrader(coreBorrow) {}
function _authorizeUpgrade(address) internal view override onlyGuardianUpgrader(core) {}

// =============================== MAIN FUNCTION ===============================

Expand All @@ -155,7 +152,7 @@ contract Distributor is UUPSHelper {
/// @param users Recipient of tokens
/// @param tokens ERC20 claimed
/// @param amounts Amount of tokens that will be sent to the corresponding users
/// @param proofs Array of hashes bridging from leaf (hash of user | token | amount) to Merkle root
/// @param proofs Array of hashes bridging from a leaf `(hash of user | token | amount)` to the Merkle root
function claim(
address[] calldata users,
address[] calldata tokens,
Expand Down Expand Up @@ -216,7 +213,7 @@ contract Distributor is UUPSHelper {
// A trusted address cannot update a tree right after a precedent tree update otherwise it can de facto
// validate a tree which has not passed the dispute period
((canUpdateMerkleRoot[msg.sender] != 1 || block.timestamp - lastTreeUpdate < disputePeriod) &&
!coreBorrow.isGovernorOrGuardian(msg.sender))
!core.isGovernorOrGuardian(msg.sender))
) revert NotTrusted();
MerkleTree memory _lastTree = tree;
tree = _tree;
Expand Down
20 changes: 20 additions & 0 deletions contracts/interfaces/ICore.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.17;

/// @title ICore
/// @author Angle Labs, Inc.
/// @notice Interface for the `Core` contracts of smart contract modules used in Angle Labs contracts
interface ICore {
/// @notice Checks whether an address is governor
/// @param admin Address to check
/// @return Whether the address has the `GOVERNOR_ROLE` or not
function isGovernor(address admin) external view returns (bool);

/// @notice Checks whether an address is a governor or a guardian of a module
/// @param admin Address to check
/// @return Whether the address has the `GUARDIAN_ROLE` or not
/// @dev Governance should make sure when adding a governor to also give this governor the guardian
/// role by calling the `addGovernor` function
function isGovernorOrGuardian(address admin) external view returns (bool);
}
28 changes: 0 additions & 28 deletions contracts/interfaces/ICoreBorrow.sol

This file was deleted.

2 changes: 1 addition & 1 deletion contracts/interfaces/ITreasury.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
pragma solidity 0.8.17;

import "./IAgToken.sol";
import "./ICoreBorrow.sol";
import "./ICore.sol";

/// @title ITreasury
/// @author Angle Core Team
Expand Down
12 changes: 6 additions & 6 deletions contracts/middleman/MerklGaugeMiddleman.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ contract MerklGaugeMiddleman {

// ================================= PARAMETERS ================================

/// @notice `CoreBorrow` contract handling access control
ICoreBorrow public coreBorrow;
/// @notice `Core` contract handling access control
ICore public core;

/// @notice Maps a gauge to its reward parameters
mapping(address => DistributionParameters) public gaugeParams;
Expand All @@ -61,9 +61,9 @@ contract MerklGaugeMiddleman {

event GaugeSet(address indexed gauge);

constructor(ICoreBorrow _coreBorrow) {
if (address(_coreBorrow) == address(0)) revert ZeroAddress();
coreBorrow = _coreBorrow;
constructor(ICore _core) {
if (address(_core) == address(0)) revert ZeroAddress();
core = _core;
IERC20 _angle = angle();
// Condition left here for testing purposes
if (address(_angle) != address(0))
Expand Down Expand Up @@ -101,7 +101,7 @@ contract MerklGaugeMiddleman {

/// @notice Specifies the reward distribution parameters for `gauge`
function setGauge(address gauge, DistributionParameters memory params) external {
if (!coreBorrow.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();
if (!core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();
DistributionCreator manager = merkleRewardManager();
if (
gauge == address(0) ||
Expand Down
2 changes: 1 addition & 1 deletion contracts/mock/MockMerklGaugeMiddleman.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ contract MockMerklGaugeMiddleman is MerklGaugeMiddleman {
IERC20 public angleAddress;
DistributionCreator public manager;

constructor(ICoreBorrow _coreBorrow) MerklGaugeMiddleman(_coreBorrow) {}
constructor(ICore _coreBorrow) MerklGaugeMiddleman(_coreBorrow) {}

function angleDistributor() public view override returns (address) {
return angleDistributorAddress;
Expand Down
11 changes: 5 additions & 6 deletions contracts/utils/UUPSHelper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,21 @@ pragma solidity ^0.8.17;

import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";

import "../interfaces/ICoreBorrow.sol";
import "../interfaces/ICore.sol";
import "../utils/Errors.sol";

/// @title UUPSHelper
/// @notice Helper contract for UUPSUpgradeable contracts where the upgradeability is controlled by a specific address
/// @author Angle Labs., Inc
/// @dev The 0 address check in the modifier allows the use of these modifiers during initialization
abstract contract UUPSHelper is UUPSUpgradeable {
modifier onlyGuardianUpgrader(ICoreBorrow _coreBorrow) {
if (address(_coreBorrow) != address(0) && !_coreBorrow.isGovernorOrGuardian(msg.sender))
revert NotGovernorOrGuardian();
modifier onlyGuardianUpgrader(ICore _core) {
if (address(_core) != address(0) && !_core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();
_;
}

modifier onlyGovernorUpgrader(ICoreBorrow _coreBorrow) {
if (address(_coreBorrow) != address(0) && !_coreBorrow.isGovernor(msg.sender)) revert NotGovernor();
modifier onlyGovernorUpgrader(ICore _core) {
if (address(_core) != address(0) && !_core.isGovernor(msg.sender)) revert NotGovernor();
_;
}

Expand Down
17 changes: 6 additions & 11 deletions deploy/0_distributor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,15 @@ const argv = yargs.env('').boolean('ci').parseSync();
const func: DeployFunction = async ({ deployments, ethers, network }) => {
const { deploy } = deployments;
const { deployer } = await ethers.getNamedSigners();
let coreBorrow: string;
/**
* TODO: change this before real deployment
*/
coreBorrow = (await deployments.get('MockCoreBorrow')).address;
/*
let core: string;

if (!network.live) {
// If we're in mainnet fork, we're using the `CoreBorrow` address from mainnet
coreBorrow = (await deployments.get('MockCoreBorrow')).address;
core = registry(ChainId.MAINNET)?.Merkl?.CoreMerkl!;
} else {
// Otherwise, we're using the proxy admin address from the desired network
coreBorrow = registry(network.config.chainId as ChainId)?.CoreBorrow!;
core = registry(network.config.chainId as ChainId)?.Merkl?.CoreMerkl!;
}
*/

console.log('Let us get started with deployment');

Expand Down Expand Up @@ -52,9 +47,9 @@ const func: DeployFunction = async ({ deployments, ethers, network }) => {
console.log(`Successfully deployed contract at the address ${distributor}`);
console.log('Initializing the contract');
const contract = new ethers.Contract(distributor, Distributor__factory.createInterface(), deployer) as Distributor;
await (await contract.connect(deployer).initialize(coreBorrow)).wait();
await (await contract.connect(deployer).initialize(core)).wait();
console.log('Contract successfully initialized');
console.log(await contract.coreBorrow());
console.log(await contract.core());

console.log('');
};
Expand Down
Loading

0 comments on commit d8ba1f1

Please sign in to comment.