Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
117 changes: 93 additions & 24 deletions contracts/registry/Registry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import "./AdminRole.sol";
import "@openzeppelin/contracts/utils/EnumerableSet.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/GSN/Context.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";

/// @title Registry tracks trusted contributors: accounts and their max trust.
// Max trust will determine the maximum amount of tokens the account can obtain.
/// @author Nelson Melina
contract Registry is Context, AdminRole {
using EnumerableSet for EnumerableSet.AddressSet;
using SafeMath for uint256;

//
// STORAGE:
Expand All @@ -29,7 +31,7 @@ contract Registry is Context, AdminRole {
mapping(address => uint256) maxTrusts;

// Mapping of account => contributor pending balance:
mapping(address => uint256) pendingBalances;
mapping(address => uint256) balances;

//
// EVENTS:
Expand All @@ -41,8 +43,11 @@ contract Registry is Context, AdminRole {
/// @dev Emit when a contributor has been removed:
event ContributorRemoved(address adr);

/// @dev Emit when a contributor's pending balance is changed:
event PendingBalanceChanged(address indexed adr, uint256 pendingBalance);
/// @dev Emit when a contributor's pending balance is set:
event PendingBalanceSet(address indexed adr, uint256 pendingBalance);

/// @dev Emit when a contributor's pending balance is risen:
event PendingBalanceRise(address indexed adr, uint256 value);

/// @dev Emit when a contributor's pending balance is cleared:
event PendingBalanceCleared(
Expand Down Expand Up @@ -83,11 +88,13 @@ contract Registry is Context, AdminRole {
/// @dev Can only be called by Admin role.
/// @param _adr (address) The address to register as contributor
/// @param _maxTrust (uint256) The amount to set as max trust
function registerContributor(address _adr, uint256 _maxTrust)
external
onlyAdmin
{
_register(_adr, _maxTrust);
/// @param _pendingBalance (uint256) The amount to set as pending balance
function registerContributor(
address _adr,
uint256 _maxTrust,
uint256 _pendingBalance
) external onlyAdmin {
_register(_adr, _maxTrust, _pendingBalance);
}

/// @notice Remove an existing contributor.
Expand All @@ -102,16 +109,18 @@ contract Registry is Context, AdminRole {
/// @param _cnt (uint256) Number of contributors to add
/// @param _adrs (address[]) Addresses to register as contributors
/// @param _trusts (uint256[]) Max trust values to set to each contributor (in order)
/// @param _pendingBalances (uint256[]) pending balance values to set to each contributor (in order)
function registerContributors(
uint256 _cnt,
address[] calldata _adrs,
uint256[] calldata _trusts
uint256[] calldata _trusts,
uint256[] calldata _pendingBalances
) external onlyAdmin {
require(_adrs.length == _cnt, "Invalid number of addresses");
require(_trusts.length == _cnt, "Invalid number of trust values");

for (uint256 i = 0; i < _cnt; i++) {
_register(_adrs[i], _trusts[i]);
_register(_adrs[i], _trusts[i], _pendingBalances[i]);
}
}

Expand All @@ -128,19 +137,26 @@ contract Registry is Context, AdminRole {
/// @notice Return contributor information about all accounts in the Registry.
/// @return contrubutors (address[]) Adresses of all contributors
/// @return trusts (uint256[]) Max trust values for all contributors, in order.
/// @return pendingBalances (uint256[]) Pending balance values for all contributors, in order.
function getContributorInfo()
external
view
returns (address[] memory contributors, uint256[] memory trusts)
returns (
address[] memory contributors,
uint256[] memory trusts,
uint256[] memory pendingBalances
)
{
contributors = EnumerableSet.enumerate(accounts);
uint256 len = contributors.length;

trusts = new uint256[](len);
pendingBalances = new uint256[](len);
for (uint256 i = 0; i < len; i++) {
trusts[i] = maxTrusts[contributors[i]];
pendingBalances[i] = balances[contributors[i]];
}
return (contributors, trusts);
return (contributors, trusts, pendingBalances);
}

/// @notice Return the max trust of an address, or 0 if the address is not a contributor.
Expand All @@ -162,7 +178,7 @@ contract Registry is Context, AdminRole {
view
returns (uint256 pendingBalance)
{
pendingBalance = pendingBalances[_adr];
pendingBalance = balances[_adr];
}

// @notice Set minter contract address
Expand All @@ -172,6 +188,7 @@ contract Registry is Context, AdminRole {

emit MinterContractSet(_minterContract);
}

// @notice Set pending balance of an address
// @param _adr (address) Address to set
// @param _pendingBalance (uint256) Pending balance of the address
Expand All @@ -182,7 +199,7 @@ contract Registry is Context, AdminRole {
_setPendingBalance(_adr, _pendingBalance);
}

/// @notice Set a list of contributors pending balance
/// @notice Set a list of contributors pending balances
/// @dev Can only be called by Admin role.
/// @param _cnt (uint256) Number of contributors to set pending balance
/// @param _adrs (address[]) Addresses to set pending balance
Expand All @@ -193,24 +210,52 @@ contract Registry is Context, AdminRole {
uint256[] calldata _pendingBalances
) external onlyAdmin {
require(_adrs.length == _cnt, "Invalid number of addresses");
require(_pendingBalances.length == _cnt, "Invalid number of trust values");
require(
_pendingBalances.length == _cnt,
"Invalid number of trust values"
);

for (uint256 i = 0; i < _cnt; i++) {
_setPendingBalance(_adrs[i], _pendingBalances[i]);
}
}

function clearPendingBalance(address _adr)
// @notice Add pending balance of an address
// @param _adr (address) Address to set
// @param _value (uint256) Value to add to pending balance of the address
function addPendingBalance(address _adr, uint256 _value)
external
onlyMinter
onlyAdmin
{
_addPendingBalance(_adr, _value);
}

/// @notice Add to a list of contributors' pending balances
/// @dev Can only be called by Admin role.
/// @param _cnt (uint256) Number of contributors to add pending balance
/// @param _adrs (address[]) Addresses to add pending balance
/// @param _values (uint256[]) Values to add to pending balance of each contributor (in order)
function addPendingBalances(
uint256 _cnt,
address[] calldata _adrs,
uint256[] calldata _values
) external onlyAdmin {
require(_adrs.length == _cnt, "Invalid number of addresses");
require(_values.length == _cnt, "Invalid number of trust values");

for (uint256 i = 0; i < _cnt; i++) {
_addPendingBalance(_adrs[i], _values[i]);
}
}

function clearPendingBalance(address _adr) external onlyMinter {
require(
_adr != address(0),
"Cannot consume pending balance for zero balance"
);

uint256 pendingBalance = pendingBalances[_adr];
delete pendingBalances[_adr];
uint256 pendingBalance = balances[_adr];
delete balances[_adr];

emit PendingBalanceCleared(_adr, pendingBalance);
}
Expand All @@ -219,7 +264,11 @@ contract Registry is Context, AdminRole {
// INTERNAL FUNCTIONS:
//

function _register(address _adr, uint256 _trust) internal {
function _register(
address _adr,
uint256 _trust,
uint256 _pendingBalance
) internal {
require(_adr != address(0), "Cannot register zero address");
require(_trust != 0, "Cannot set a max trust of 0");

Expand All @@ -228,6 +277,7 @@ contract Registry is Context, AdminRole {
"Contributor already registered"
);
maxTrusts[_adr] = _trust;
balances[_adr] = _pendingBalance;

emit ContributorAdded(_adr);
}
Expand All @@ -238,12 +288,30 @@ contract Registry is Context, AdminRole {

EnumerableSet.remove(accounts, _adr);
delete maxTrusts[_adr];
delete pendingBalances[_adr];
delete balances[_adr];

emit ContributorRemoved(_adr);
}

function _setPendingBalance(address _adr, uint256 _pendingBalance) internal {
function _setPendingBalance(address _adr, uint256 _pendingBalance)
internal
{
require(
_adr != address(0),
"Cannot set pending balance for zero balance"
);
require(maxTrusts[_adr] != 0, "Address is not a contributor");
require(
cstkToken.balanceOf(_adr) == 0,
"User has activated his membership"
);

balances[_adr] = _pendingBalance;

emit PendingBalanceSet(_adr, _pendingBalance);
}

function _addPendingBalance(address _adr, uint256 _value) internal {
require(
_adr != address(0),
"Cannot set pending balance for zero balance"
Expand All @@ -254,8 +322,9 @@ contract Registry is Context, AdminRole {
"User has activated his membership"
);

pendingBalances[_adr] = _pendingBalance;
uint256 newPendingBalance = balances[_adr].add(_value);
balances[_adr] = newPendingBalance;

emit PendingBalanceChanged(_adr, _pendingBalance);
emit PendingBalanceRise(_adr, _value);
}
}
Loading