Skip to content

Commit

Permalink
NatSpec and API cleanup for Registry, Pool (#1182)
Browse files Browse the repository at this point in the history
* registry naming and natspec consistency

* pool natspec updates

* natspec and naming updates for pool

* update pool tests with admin functions
  • Loading branch information
dmosites authored Aug 21, 2023
1 parent 211b003 commit b5daf33
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 198 deletions.
160 changes: 80 additions & 80 deletions source/pool/contracts/Pool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import "./interfaces/IPool.sol";

/**
* @title AirSwap: Rewards Pool
* @title AirSwap: Withdrawable Token Pool
* @notice https://www.airswap.io/
*/
contract Pool is IPool, Ownable2Step {
Expand All @@ -24,19 +24,19 @@ contract Pool is IPool, Ownable2Step {
// Max percentage for a claim with infinite value
uint256 public max;

// Mapping of address to boolean to enable admin accounts
// Mapping of address to boolean for admin accounts
mapping(address => bool) public admins;

// Mapping of tree -> account -> has claimed
// Mapping of tree to account to claim status
mapping(bytes32 => mapping(address => bool)) public claimed;

// Mapping of tree -> root
// Mapping of tree to root
mapping(bytes32 => bytes32) public rootsByTree;

/**
* @notice Constructor
* @param _scale uint256 scale param for calculating claim amount
* @param _max uint256 max param for calculating claim amount
* @param _scale uint256 scale to calculate withdrawal amount
* @param _max uint256 max to calculate withdrawal amount
*/
constructor(uint256 _scale, uint256 _max) {
if (_max > MAX_PERCENTAGE) revert MaxTooHigh(_max);
Expand All @@ -46,17 +46,34 @@ contract Pool is IPool, Ownable2Step {
}

/**
* @dev Reverts if called by any account other than an admin.
* @dev Revert if called by non admin account
*/
modifier multiAdmin() {
if (!admins[msg.sender]) revert Unauthorized();
_;
}

/**
* @notice Set scale
* @notice Transfer out token balances for migrations
* @param _tokens address[] token balances to transfer
* @param _dest address destination
* @dev Only owner
*/
function drainTo(
address[] calldata _tokens,
address _dest
) external override onlyOwner {
for (uint256 i = 0; i < _tokens.length; i++) {
uint256 _bal = IERC20(_tokens[i]).balanceOf(address(this));
IERC20(_tokens[i]).safeTransfer(_dest, _bal);
}
emit DrainTo(_tokens, _dest);
}

/**
* @notice Set withdrawal scale
* @param _scale uint256 scale to calculate withdrawal amount
* @dev Only owner
* @param _scale uint256 scale param for calculating claim amount
*/
function setScale(uint256 _scale) external override onlyOwner {
if (_scale > MAX_SCALE) revert ScaleTooHigh(_scale);
Expand All @@ -65,9 +82,9 @@ contract Pool is IPool, Ownable2Step {
}

/**
* @notice Set max
* @notice Set withdrawal max
* @param _max uint256 max to calculate withdrawal amount
* @dev Only owner
* @param _max uint256 max param for calculating claim amount
*/
function setMax(uint256 _max) external override onlyOwner {
if (_max > MAX_PERCENTAGE) revert MaxTooHigh(_max);
Expand All @@ -76,86 +93,48 @@ contract Pool is IPool, Ownable2Step {
}

/**
* @notice Add admin address
* @notice Set an admin
* @param _admin address to set as admin
* @dev Only owner
* @param _admin address to add
*/
function addAdmin(address _admin) external override onlyOwner {
function setAdmin(address _admin) external override onlyOwner {
if (_admin == address(0)) revert AddressInvalid(_admin);
admins[_admin] = true;
emit AddAdmin(_admin);
emit SetAdmin(_admin);
}

/**
* @notice Remove admin address
* @notice Unset an admin
* @param _admin address to unset as admin
* @dev Only owner
* @param _admin address to remove
*/
function removeAdmin(address _admin) external override onlyOwner {
function unsetAdmin(address _admin) external override onlyOwner {
if (admins[_admin] != true) revert AdminNotSet(_admin);
admins[_admin] = false;
emit RemoveAdmin(_admin);
emit UnsetAdmin(_admin);
}

/**
* @notice Enables claims for a merkle tree of a set of values by setting the
* merkle root
* @param _tree bytes32 The merkle tree unique identifier.
* @param _root bytes32 The merkle root.
* @notice Enable claims for a merkle tree
* @param _tree bytes32 a tree identifier
* @param _root bytes32 a tree root
*/
function enable(bytes32 _tree, bytes32 _root) external override multiAdmin {
rootsByTree[_tree] = _root;
emit Enable(_tree, _root);
}

/**
* @notice Returns the claim status of a set of roots for a given address
* @param _account address The address to check.
* @param _trees bytes32[] An array of tree identifiers.
* @return claimList bool[] An array of claim statuses.
*/
function getClaimStatusForTrees(
address _account,
bytes32[] calldata _trees
) external view returns (bool[] memory) {
bool[] memory claimList = new bool[](_trees.length);
for (uint256 i = 0; i < _trees.length; i++) {
claimList[i] = claimed[_trees[i]][_account];
}
return claimList;
}

/**
* @notice Admin function to migrate funds
* @dev Only owner
* @param _tokens address[] addresses of tokens to migrate
* @param _dest address destination address
*/
function drainTo(
address[] calldata _tokens,
address _dest
) external override onlyOwner {
for (uint256 i = 0; i < _tokens.length; i++) {
uint256 _bal = IERC20(_tokens[i]).balanceOf(address(this));
IERC20(_tokens[i]).safeTransfer(_dest, _bal);
}
emit DrainTo(_tokens, _dest);
}

/**
* @notice Withdraw tokens from the pool using one or more claims, sending
* the tokens to the passed recipient address.
* @param _claims Claim[] A set of claims each consisting of a tree id, a
* points earned, and a merkle proof.
* @param _token address The address of the token to withdraw.
* @param _minimumAmount uint256 The minimum amount to withdraw - this acts
* as slippage / frontrunning protection.
* @param _recipient address The address to send the tokens to.
* @notice Withdraw tokens using claims
* @param _claims Claim[] a set of claims
* @param _token address of a token to withdraw
* @param _minimum uint256 minimum expected amount
* @param _recipient address to receive withdrawal
*/
function withdraw(
Claim[] memory _claims,
address _token,
uint256 _minimumAmount,
uint256 _minimum,
address _recipient
) public override returns (uint256 _amount) {
if (_claims.length <= 0) revert ClaimsNotProvided();
Expand All @@ -165,6 +144,7 @@ contract Pool is IPool, Ownable2Step {
bytes32[] memory _treeList = new bytes32[](_claims.length);
uint256 _totalValue = 0;

// Iterate through claims to determine total value
for (uint256 i = 0; i < _claims.length; i++) {
_claim = _claims[i];
_root = rootsByTree[_claim.tree];
Expand All @@ -179,42 +159,62 @@ contract Pool is IPool, Ownable2Step {
_treeList[i] = _claim.tree;
}

// Determine withdrawable amount given total value
_amount = calculate(_totalValue, _token);
if (_amount < _minimumAmount) revert AmountInsufficient(_amount);
if (_amount < _minimum) revert AmountInsufficient(_amount);

// Transfer withdrawable amount to recipient
IERC20(_token).safeTransfer(_recipient, _amount);
emit Withdraw(_treeList, msg.sender, _token, _amount);
}

/**
* @notice Calculate output amount for a given input amount and token
* @param _value uint256 input amount
* @param _token address token address to withdraw from the pool
* @return amount uint256 amount withdrawable based on balance, scale, and max
* @notice Calculate amount for a value and token
* @param _value uint256 claim value
* @param _token address claim token
* @return uint256 amount withdrawable
*/
function calculate(
uint256 _value,
address _token
) public view override returns (uint256 amount) {
) public view override returns (uint256) {
uint256 _balance = IERC20(_token).balanceOf(address(this));
uint256 _divisor = (uint256(10) ** scale) + _value;
return (max * _value * _balance) / _divisor / 100;
}

/**
* @notice Verify a claim's merkle proof
* @param _participant address The address of the claimant
* @param _root bytes32 The merkle root
* @param _value uint256 The value of the claim
* @param _proof bytes32[] The provided merkle proof
* @notice Verify a merkle proof
* @param _claimant address of the claimant
* @param _root bytes32 merkle root
* @param _value uint256 merkle value
* @param _proof bytes32[] merkle proof
* @return bool whether verified
*/
function verify(
address _participant,
address _claimant,
bytes32 _root,
uint256 _value,
bytes32[] memory _proof
) public pure override returns (bool valid) {
bytes32 _leaf = keccak256(abi.encodePacked(_participant, _value));
) public pure override returns (bool) {
bytes32 _leaf = keccak256(abi.encodePacked(_claimant, _value));
return MerkleProof.verify(_proof, _root, _leaf);
}

/**
* @notice Get claim status for an account and set of trees
* @param _account address to check
* @param _trees bytes32[] an array of tree identifiers
* @return statuses bool[] an array of claim statuses
*/
function getStatus(
address _account,
bytes32[] calldata _trees
) external view returns (bool[] memory) {
bool[] memory statuses = new bool[](_trees.length);
for (uint256 i = 0; i < _trees.length; i++) {
statuses[i] = claimed[_trees[i]][_account];
}
return statuses;
}
}
18 changes: 9 additions & 9 deletions source/pool/contracts/interfaces/IPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ interface IPool {
bytes32[] proof;
}

event AddAdmin(address admin);
event DrainTo(address[] tokens, address dest);
event Enable(bytes32 tree, bytes32 root);
event SetAdmin(address admin);
event SetMax(uint256 max);
event SetScale(uint256 scale);
event RemoveAdmin(address admin);
event UnsetAdmin(address admin);
event Withdraw(
bytes32[] trees,
address account,
Expand All @@ -38,23 +38,23 @@ interface IPool {

function setMax(uint256 _max) external;

function addAdmin(address _admin) external;
function setAdmin(address _admin) external;

function removeAdmin(address _admin) external;
function unsetAdmin(address _admin) external;

function enable(bytes32 _tree, bytes32 _root) external;
function drainTo(address[] calldata tokens, address dest) external;

function getClaimStatusForTrees(
function getStatus(
address _account,
bytes32[] calldata _trees
) external returns (bool[] memory claimStatusList);
) external returns (bool[] memory statuses);

function drainTo(address[] calldata tokens, address dest) external;
function enable(bytes32 _tree, bytes32 _root) external;

function withdraw(
Claim[] memory claims,
address token,
uint256 minimumAmount,
uint256 minimum,
address recipient
) external returns (uint256 amount);

Expand Down
Loading

0 comments on commit b5daf33

Please sign in to comment.