Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

F pending balance #42

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 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
6 changes: 6 additions & 0 deletions contracts/Minter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ contract Minter is AdminRole {
// Get the current CSTK balance of the recipient account.
uint256 recipientBalance = cstkToken.balanceOf(recipient);

// It's activating membership too
if (recipientBalance == 0) {
toMint = toMint + registry.getPendingBalance(recipient);
registry.clearPendingBalance(recipient);
}

// The recipient cannot receive more than the following amount of tokens:
// maxR := maxTrust[recipient] * TOTAL_SUPPLY / 10000000.
uint256 maxToReceive = maxTrust.mul(totalSupply).div(
Expand Down
98 changes: 96 additions & 2 deletions contracts/registry/Registry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ pragma solidity ^0.5.17;
import "./AdminRole.sol";

import "@openzeppelin/contracts/utils/EnumerableSet.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/GSN/Context.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 AdminRole {
contract Registry is Context, AdminRole {
using EnumerableSet for EnumerableSet.AddressSet;

//
Expand All @@ -17,9 +19,18 @@ contract Registry is AdminRole {
// EnumerableSet of all trusted accounts:
EnumerableSet.AddressSet internal accounts;

// CS token contract
IERC20 internal cstkToken;

// Minter contract address
address private minterContract;

// Mapping of account => contributor max trust:
mapping(address => uint256) maxTrusts;

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

//
// EVENTS:
//
Expand All @@ -30,13 +41,39 @@ contract Registry is 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 cleared:
event PendingBalanceCleared(
address indexed adr,
uint256 consumedPendingBalance
);

/// @dev Emit when minter contract address is set
event MinterContractSet(address indexed adr);

//
// CONSTRUCTOR:
//

/// @dev Construct the Registry,
/// @param _admins (address[]) List of admins for the Registry contract.
constructor(address[] memory _admins) public AdminRole(_admins) {}
/// @param _cstkTokenAddress (address) CS token deployed contract address
constructor(address[] memory _admins, address _cstkTokenAddress)
public
AdminRole(_admins)
{
cstkToken = IERC20(_cstkTokenAddress);
}

modifier onlyMinter() {
require(
_msgSender() == minterContract,
"Caller is not Minter Contract"
);
_;
}

//
// EXTERNAL FUNCTIONS:
Expand Down Expand Up @@ -117,6 +154,62 @@ contract Registry is AdminRole {
return maxTrusts[_adr];
}

/// @notice Return the pending balance of an address, or 0 if the address is not a contributor.
/// @param _adr (address) Address to check
/// @return pendingBalance (uint256) Pending balance of the address, or 0 if not a contributor.
function getPendingBalance(address _adr)
external
view
returns (uint256 pendingBalance)
{
pendingBalance = pendingBalances[_adr];
}

// @notice Set minter contract address
// @param _minterContract (address) Address to set
function setMinterContract(address _minterContract) external onlyAdmin {
minterContract = _minterContract;

emit MinterContractSet(_minterContract);
}

// @notice Set pending balance of an address
// @param _adr (address) Address to set
// @param _pendingBalance (uint256) Pending balance of the address
function setPendingBalance(address _adr, uint256 _pendingBalance)
external
onlyAdmin
{
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"
);

pendingBalances[_adr] = _pendingBalance;

emit PendingBalanceChanged(_adr, _pendingBalance);
}

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

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

emit PendingBalanceCleared(_adr, pendingBalance);
}

//
// INTERNAL FUNCTIONS:
//
Expand All @@ -140,6 +233,7 @@ contract Registry is AdminRole {

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

emit ContributorRemoved(_adr);
}
Expand Down
37 changes: 21 additions & 16 deletions buidler.config.ts → hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { BuidlerConfig, task, usePlugin } from "@nomiclabs/buidler/config";
import { HardhatUserConfig, task } from "hardhat/config";
import { generate, get } from "./scripts/accounts";

import { remove } from "fs-extra";
import "@nomiclabs/hardhat-ethers";
import "@nomiclabs/hardhat-etherscan";

require("dotenv-safe").config();
import "hardhat-deploy";
import "hardhat-gas-reporter";
import "solidity-coverage";

usePlugin("@nomiclabs/buidler-ethers");
usePlugin("@nomiclabs/buidler-etherscan");
usePlugin("buidler-deploy");
usePlugin("buidler-gas-reporter");
usePlugin("solidity-coverage");
require("dotenv-safe").config({
allowEmptyValues: true,
});

require("./scripts/trustedAccounts");
require("./scripts/addTrusted");
Expand All @@ -26,7 +28,7 @@ const SOLC_VERSION = process.env.SOLC_VERSION || "";
const SOLC_OPTIMIZER_ENABLED = process.env.SOLC_OPTIMIZER_ENABLED === "true";
const GAS_REPORTER_ENABLED = process.env.GAS_REPORTER_ENABLED === "true";

const config: BuidlerConfig = {
const config: HardhatUserConfig = {
paths: {
artifacts: "build/contracts",
cache: "build/cache",
Expand All @@ -35,7 +37,7 @@ const config: BuidlerConfig = {
tests: "test",
},
networks: {
buidlerevm: {
hardhat: {
accounts: generate(MNEMONIC, DEVCHAIN_ACCOUNT_NUM, DEVCHAIN_BALANCE_ETH),
},
local: {
Expand All @@ -61,21 +63,24 @@ const config: BuidlerConfig = {
drainVaultReceiver: { default: 0 },
escapeHatchCaller: { default: 0 },
escapeHatchDestination: { default: 0 },
other: { default: 9 },
other: { default: 8 },
otherSecond: { default: 9 },
},
solc: {
solidity: {
version: SOLC_VERSION,
optimizer: {
runs: 200,
enabled: SOLC_OPTIMIZER_ENABLED,
settings: {
optimizer: {
runs: 200,
enabled: SOLC_OPTIMIZER_ENABLED,
},
},
},
gasReporter: {
enabled: GAS_REPORTER_ENABLED,
artifactType: "buidler-v1",
// artifactType: "buidler-v1",
},
etherscan: {
url: "https://api.etherscan.io/api",
// url: "https://api.etherscan.io/api",
apiKey: ETHERSCAN_API_KEY,
},
};
Expand Down
Loading