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

test #243

Draft
wants to merge 12 commits into
base: master
Choose a base branch
from
Binary file added .DS_Store
Binary file not shown.
34 changes: 34 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Run Tests

on:
push:
branches:
- master

pull_request:
branches:
- master

jobs:
test:
strategy:
matrix:
node-version: [12, 14, 16]

runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Setup Node
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}

- name: Update NPM
run: npm install -g npm@latest

- name: Install Dependencies
run: npm i

- name: Run Tests
run: npm test
10 changes: 9 additions & 1 deletion contracts/contract/RocketBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,15 @@ abstract contract RocketBase {
// Return
return contractAddress;
}

/// @dev Get the address of a network contract by name
function getPublicContractAddress(string memory _contractName) external view returns (address) {
// Get the current contract address
address contractAddress = getAddress(keccak256(abi.encodePacked("contract.address", _contractName)));
// Check it
require(contractAddress != address(0x0), "Contract not found");
// Return
return contractAddress;
}

/// @dev Get the address of a network contract by name (returns address(0x0) instead of reverting if contract does not exist)
function getContractAddressUnsafe(string memory _contractName) internal view returns (address) {
Expand Down
2 changes: 1 addition & 1 deletion contracts/contract/RocketVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20Burnable.sol";

// ETH and rETH are stored here to prevent contract upgrades from affecting balances
// ETH and ggpAVAX are stored here to prevent contract upgrades from affecting balances
// The RocketVault contract must not be upgraded

contract RocketVault is RocketBase, RocketVaultInterface {
Expand Down
156 changes: 78 additions & 78 deletions contracts/contract/auction/RocketAuctionManager.sol

Large diffs are not rendered by default.

248 changes: 160 additions & 88 deletions contracts/contract/dao/node/RocketDAONodeTrusted.sol

Large diffs are not rendered by default.

72 changes: 36 additions & 36 deletions contracts/contract/dao/node/RocketDAONodeTrustedActions.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ contract RocketDAONodeTrustedActions is RocketBase, RocketDAONodeTrustedActionsI
using SafeMath for uint;

// Events
event ActionJoined(address indexed nodeAddress, uint256 rplBondAmount, uint256 time);
event ActionLeave(address indexed nodeAddress, uint256 rplBondAmount, uint256 time);
event ActionKick(address indexed nodeAddress, uint256 rplBondAmount, uint256 time);
event ActionJoined(address indexed nodeAddress, uint256 ggpBondAmount, uint256 time);
event ActionLeave(address indexed nodeAddress, uint256 ggpBondAmount, uint256 time);
event ActionKick(address indexed nodeAddress, uint256 ggpBondAmount, uint256 time);
event ActionChallengeMade(address indexed nodeChallengedAddress, address indexed nodeChallengerAddress, uint256 time);
event ActionChallengeDecided(address indexed nodeChallengedAddress, address indexed nodeChallengeDeciderAddress, bool success, uint256 time);

Expand All @@ -42,7 +42,7 @@ contract RocketDAONodeTrustedActions is RocketBase, RocketDAONodeTrustedActionsI
/*** Internal Methods **********************/

// Add a new member to the DAO
function _memberAdd(address _nodeAddress, uint256 _rplBondAmountPaid) private onlyRegisteredNode(_nodeAddress) {
function _memberAdd(address _nodeAddress, uint256 _ggpBondAmountPaid) private onlyRegisteredNode(_nodeAddress) {
// Load contracts
RocketClaimTrustedNodeInterface rocketClaimTrustedNode = RocketClaimTrustedNodeInterface(getContractAddress("rocketClaimTrustedNode"));
RocketDAONodeTrustedInterface rocketDAONode = RocketDAONodeTrustedInterface(getContractAddress("rocketDAONodeTrusted"));
Expand All @@ -52,7 +52,7 @@ contract RocketDAONodeTrustedActions is RocketBase, RocketDAONodeTrustedActionsI
// Flag them as a member now that they have accepted the invitation and record the size of the bond they paid
setBool(keccak256(abi.encodePacked(daoNameSpace, "member", _nodeAddress)), true);
// Add the bond amount they have paid
if(_rplBondAmountPaid > 0) setUint(keccak256(abi.encodePacked(daoNameSpace, "member.bond.rpl", _nodeAddress)), _rplBondAmountPaid);
if(_ggpBondAmountPaid > 0) setUint(keccak256(abi.encodePacked(daoNameSpace, "member.bond.ggp", _nodeAddress)), _ggpBondAmountPaid);
// Record the block number they joined at
setUint(keccak256(abi.encodePacked(daoNameSpace, "member.joined.time", _nodeAddress)), block.timestamp);
// Add to member index now
Expand All @@ -73,7 +73,7 @@ contract RocketDAONodeTrustedActions is RocketBase, RocketDAONodeTrustedActionsI
deleteAddress(keccak256(abi.encodePacked(daoNameSpace, "member.address", _nodeAddress)));
deleteString(keccak256(abi.encodePacked(daoNameSpace, "member.id", _nodeAddress)));
deleteString(keccak256(abi.encodePacked(daoNameSpace, "member.url", _nodeAddress)));
deleteUint(keccak256(abi.encodePacked(daoNameSpace, "member.bond.rpl", _nodeAddress)));
deleteUint(keccak256(abi.encodePacked(daoNameSpace, "member.bond.ggp", _nodeAddress)));
deleteUint(keccak256(abi.encodePacked(daoNameSpace, "member.joined.time", _nodeAddress)));
deleteUint(keccak256(abi.encodePacked(daoNameSpace, "member.challenged.time", _nodeAddress)));
// Clean up the invited/leave proposals
Expand All @@ -87,9 +87,9 @@ contract RocketDAONodeTrustedActions is RocketBase, RocketDAONodeTrustedActionsI
function _memberJoin(address _nodeAddress) private {
// Set some intiial contract address
address rocketVaultAddress = getContractAddress("rocketVault");
address rocketTokenRPLAddress = getContractAddress("rocketTokenRPL");
address GoGoTokenGGPAddress = getContractAddress("gogoTokenGGP");
// Load contracts
IERC20 rplInflationContract = IERC20(rocketTokenRPLAddress);
IERC20 ggpInflationContract = IERC20(GoGoTokenGGPAddress);
RocketVaultInterface rocketVault = RocketVaultInterface(rocketVaultAddress);
RocketDAONodeTrustedInterface rocketDAONode = RocketDAONodeTrustedInterface(getContractAddress("rocketDAONodeTrusted"));
RocketDAONodeTrustedSettingsMembersInterface rocketDAONodeTrustedSettingsMembers = RocketDAONodeTrustedSettingsMembersInterface(getContractAddress("rocketDAONodeTrustedSettingsMembers"));
Expand All @@ -98,41 +98,41 @@ contract RocketDAONodeTrustedActions is RocketBase, RocketDAONodeTrustedActionsI
uint256 memberInvitedTime = rocketDAONode.getMemberProposalExecutedTime("invited", _nodeAddress);
// Have they been invited?
require(memberInvitedTime > 0, "This node has not been invited to join");
// The current member bond amount in RPL that's required
uint256 rplBondAmount = rocketDAONodeTrustedSettingsMembers.getRPLBond();
// The current member bond amount in GGP that's required
uint256 ggpBondAmount = rocketDAONodeTrustedSettingsMembers.getGGPBond();
// Has their invite expired?
require(memberInvitedTime.add(rocketDAONodeTrustedSettingsProposals.getActionTime()) > block.timestamp, "This node's invitation to join has expired, please apply again");
// Verify they have allowed this contract to spend their RPL for the bond
require(rplInflationContract.allowance(_nodeAddress, address(this)) >= rplBondAmount, "Not enough allowance given to RocketDAONodeTrusted contract for transfer of RPL bond tokens");
// Verify they have allowed this contract to spend their GGP for the bond
require(ggpInflationContract.allowance(_nodeAddress, address(this)) >= ggpBondAmount, "Not enough allowance given to RocketDAONodeTrusted contract for transfer of GGP bond tokens");
// Transfer the tokens to this contract now
require(rplInflationContract.transferFrom(_nodeAddress, address(this), rplBondAmount), "Token transfer to RocketDAONodeTrusted contract was not successful");
require(ggpInflationContract.transferFrom(_nodeAddress, address(this), ggpBondAmount), "Token transfer to RocketDAONodeTrusted contract was not successful");
// Allow RocketVault to transfer these tokens to itself now
require(rplInflationContract.approve(rocketVaultAddress, rplBondAmount), "Approval for RocketVault to spend RocketDAONodeTrusted RPL bond tokens was not successful");
require(ggpInflationContract.approve(rocketVaultAddress, ggpBondAmount), "Approval for RocketVault to spend RocketDAONodeTrusted GGP bond tokens was not successful");
// Let vault know it can move these tokens to itself now and credit the balance to this contract
rocketVault.depositToken(getContractName(address(this)), IERC20(rocketTokenRPLAddress), rplBondAmount);
rocketVault.depositToken(getContractName(address(this)), IERC20(GoGoTokenGGPAddress), ggpBondAmount);
// Add them as a member now that they have accepted the invitation and record the size of the bond they paid
_memberAdd(_nodeAddress, rplBondAmount);
_memberAdd(_nodeAddress, ggpBondAmount);
// Log it
emit ActionJoined(_nodeAddress, rplBondAmount, block.timestamp);
emit ActionJoined(_nodeAddress, ggpBondAmount, block.timestamp);
}

/*** Action Methods ************************/

// When a new member has been successfully invited to join, they must call this method to join officially
// They will be required to have the RPL bond amount in their account
// They will be required to have the GGP bond amount in their account
// This method allows us to only allow them to join if they have a working node account and have been officially invited
function actionJoin() override external onlyRegisteredNode(msg.sender) onlyLatestContract("rocketDAONodeTrustedActions", address(this)) {
_memberJoin(msg.sender);
}

// When the DAO has suffered a loss of members due to unforseen blackswan issue and has < the min required amount (3), a regular bonded node can directly join as a member and recover the DAO
// They will be required to have the RPL bond amount in their account. This is called directly from RocketDAONodeTrusted.
// They will be required to have the GGP bond amount in their account. This is called directly from RocketDAONodeTrusted.
function actionJoinRequired(address _nodeAddress) override external onlyRegisteredNode(_nodeAddress) onlyLatestContract("rocketDAONodeTrusted", msg.sender) {
_memberJoin(_nodeAddress);
}

// When a new member has successfully requested to leave with a proposal, they must call this method to leave officially and receive their RPL bond
function actionLeave(address _rplBondRefundAddress) override external onlyTrustedNode(msg.sender) onlyLatestContract("rocketDAONodeTrustedActions", address(this)) {
// When a new member has successfully requested to leave with a proposal, they must call this method to leave officially and receive their GGP bond
function actionLeave(address _ggpBondRefundAddress) override external onlyTrustedNode(msg.sender) onlyLatestContract("rocketDAONodeTrustedActions", address(this)) {
// Load contracts
RocketVaultInterface rocketVault = RocketVaultInterface(getContractAddress("rocketVault"));
RocketDAONodeTrustedInterface rocketDAONode = RocketDAONodeTrustedInterface(getContractAddress("rocketDAONodeTrusted"));
Expand All @@ -143,44 +143,44 @@ contract RocketDAONodeTrustedActions is RocketBase, RocketDAONodeTrustedActionsI
uint256 leaveAcceptedTime = rocketDAONode.getMemberProposalExecutedTime("leave", msg.sender);
// Has their leave request expired?
require(leaveAcceptedTime.add(rocketDAONodeTrustedSettingsProposals.getActionTime()) > block.timestamp, "This member has not been approved to leave or request has expired, please apply to leave again");
// They were successful, lets refund their RPL Bond
uint256 rplBondRefundAmount = rocketDAONode.getMemberRPLBondAmount(msg.sender);
// They were successful, lets refund their GGP Bond
uint256 ggpBondRefundAmount = rocketDAONode.getMemberGGPBondAmount(msg.sender);
// Refund
if(rplBondRefundAmount > 0) {
if(ggpBondRefundAmount > 0) {
// Valid withdrawal address
require(_rplBondRefundAddress != address(0x0), "Member has not supplied a valid address for their RPL bond refund");
require(_ggpBondRefundAddress != address(0x0), "Member has not supplied a valid address for their GGP bond refund");
// Send tokens now
rocketVault.withdrawToken(_rplBondRefundAddress, IERC20(getContractAddress("rocketTokenRPL")), rplBondRefundAmount);
rocketVault.withdrawToken(_ggpBondRefundAddress, IERC20(getContractAddress("gogoTokenGGP")), ggpBondRefundAmount);
}
// Remove them now
_memberRemove(msg.sender);
// Log it
emit ActionLeave(msg.sender, rplBondRefundAmount, block.timestamp);
emit ActionLeave(msg.sender, ggpBondRefundAmount, block.timestamp);
}


// A member can be evicted from the DAO by proposal, send their remaining RPL balance to them and remove from the DAO
// A member can be evicted from the DAO by proposal, send their remaining GGP balance to them and remove from the DAO
// Is run via the main DAO contract when the proposal passes and is executed
function actionKick(address _nodeAddress, uint256 _rplFine) override external onlyTrustedNode(_nodeAddress) onlyLatestContract("rocketDAONodeTrustedProposals", msg.sender) {
function actionKick(address _nodeAddress, uint256 _ggpFine) override external onlyTrustedNode(_nodeAddress) onlyLatestContract("rocketDAONodeTrustedProposals", msg.sender) {
// Load contracts
RocketVaultInterface rocketVault = RocketVaultInterface(getContractAddress("rocketVault"));
RocketDAONodeTrustedInterface rocketDAONode = RocketDAONodeTrustedInterface(getContractAddress("rocketDAONodeTrusted"));
IERC20 rplToken = IERC20(getContractAddress("rocketTokenRPL"));
IERC20 ggpToken = IERC20(getContractAddress("gogoTokenGGP"));
// Get the
uint256 rplBondRefundAmount = rocketDAONode.getMemberRPLBondAmount(_nodeAddress);
uint256 ggpBondRefundAmount = rocketDAONode.getMemberGGPBondAmount(_nodeAddress);
// Refund
if (rplBondRefundAmount > 0) {
if (ggpBondRefundAmount > 0) {
// Send tokens now if the vault can cover it
if(rplToken.balanceOf(address(rocketVault)) >= rplBondRefundAmount) rocketVault.withdrawToken(_nodeAddress, IERC20(getContractAddress("rocketTokenRPL")), rplBondRefundAmount);
if(ggpToken.balanceOf(address(rocketVault)) >= ggpBondRefundAmount) rocketVault.withdrawToken(_nodeAddress, IERC20(getContractAddress("gogoTokenGGP")), ggpBondRefundAmount);
}
// Burn the fine
if (_rplFine > 0) {
rocketVault.burnToken(ERC20Burnable(getContractAddress("rocketTokenRPL")), _rplFine);
if (_ggpFine > 0) {
rocketVault.burnToken(ERC20Burnable(getContractAddress("gogoTokenGGP")), _ggpFine);
}
// Remove the member now
_memberRemove(_nodeAddress);
// Log it
emit ActionKick(_nodeAddress, rplBondRefundAmount, block.timestamp);
emit ActionKick(_nodeAddress, ggpBondRefundAmount, block.timestamp);
}


Expand Down
18 changes: 9 additions & 9 deletions contracts/contract/dao/node/RocketDAONodeTrustedProposals.sol
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ contract RocketDAONodeTrustedProposals is RocketBase, RocketDAONodeTrustedPropos
}


// A current member proposes leaving the trusted node DAO, when successful they will be allowed to collect their RPL bond
// A current member proposes leaving the trusted node DAO, when successful they will be allowed to collect their GGP bond
function proposalLeave(address _nodeAddress) override external onlyExecutingContracts onlyTrustedNode(_nodeAddress) {
// Load contracts
RocketDAONodeTrustedInterface daoNodeTrusted = RocketDAONodeTrustedInterface(getContractAddress("rocketDAONodeTrusted"));
Expand All @@ -108,19 +108,19 @@ contract RocketDAONodeTrustedProposals is RocketBase, RocketDAONodeTrustedPropos
}


// Propose to kick a current member from the DAO with an optional RPL bond fine
function proposalKick(address _nodeAddress, uint256 _rplFine) override external onlyExecutingContracts onlyTrustedNode(_nodeAddress) {
// Propose to kick a current member from the DAO with an optional GGP bond fine
function proposalKick(address _nodeAddress, uint256 _ggpFine) override external onlyExecutingContracts onlyTrustedNode(_nodeAddress) {
// Load contracts
RocketDAONodeTrustedInterface daoNodeTrusted = RocketDAONodeTrustedInterface(getContractAddress("rocketDAONodeTrusted"));
RocketDAONodeTrustedActionsInterface daoActionsContract = RocketDAONodeTrustedActionsInterface(getContractAddress("rocketDAONodeTrustedActions"));
// How much is their RPL bond?
uint256 rplBondAmount = daoNodeTrusted.getMemberRPLBondAmount(_nodeAddress);
// How much is their GGP bond?
uint256 ggpBondAmount = daoNodeTrusted.getMemberGGPBondAmount(_nodeAddress);
// Check fine amount can be covered
require(_rplFine <= rplBondAmount, "RPL Fine must be lower or equal to the RPL bond amount of the node being kicked");
require(_ggpFine <= ggpBondAmount, "GGP Fine must be lower or equal to the GGP bond amount of the node being kicked");
// Set their bond amount minus the fine
setUint(keccak256(abi.encodePacked(daoNameSpace, "member.bond.rpl", _nodeAddress)), rplBondAmount.sub(_rplFine));
setUint(keccak256(abi.encodePacked(daoNameSpace, "member.bond.ggp", _nodeAddress)), ggpBondAmount.sub(_ggpFine));
// Kick them now
daoActionsContract.actionKick(_nodeAddress, _rplFine);
daoActionsContract.actionKick(_nodeAddress, _ggpFine);
}


Expand Down Expand Up @@ -171,7 +171,7 @@ contract RocketDAONodeTrustedProposals is RocketBase, RocketDAONodeTrustedPropos
setAddress(keccak256(abi.encodePacked(daoNameSpace, "member.address", _nodeAddress)), _nodeAddress);
setString(keccak256(abi.encodePacked(daoNameSpace, "member.id", _nodeAddress)), _id);
setString(keccak256(abi.encodePacked(daoNameSpace, "member.url", _nodeAddress)), _url);
setUint(keccak256(abi.encodePacked(daoNameSpace, "member.bond.rpl", _nodeAddress)), 0);
setUint(keccak256(abi.encodePacked(daoNameSpace, "member.bond.ggp", _nodeAddress)), 0);
setUint(keccak256(abi.encodePacked(daoNameSpace, "member.joined.time", _nodeAddress)), 0);
}

Expand Down
8 changes: 4 additions & 4 deletions contracts/contract/dao/node/RocketDAONodeTrustedUpgrade.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ contract RocketDAONodeTrustedUpgrade is RocketBase, RocketDAONodeTrustedUpgradeI
// Check contract being upgraded
bytes32 nameHash = keccak256(abi.encodePacked(_name));
require(nameHash != keccak256(abi.encodePacked("rocketVault")), "Cannot upgrade the vault");
require(nameHash != keccak256(abi.encodePacked("rocketTokenRETH")), "Cannot upgrade token contracts");
require(nameHash != keccak256(abi.encodePacked("rocketTokenRPL")), "Cannot upgrade token contracts");
require(nameHash != keccak256(abi.encodePacked("rocketTokenRPLFixedSupply")), "Cannot upgrade token contracts");
require(nameHash != keccak256(abi.encodePacked("casperDeposit")), "Cannot upgrade the casper deposit contract");
require(nameHash != keccak256(abi.encodePacked("gogoTokenGGPAVAX")), "Cannot upgrade token contracts");
require(nameHash != keccak256(abi.encodePacked("gogoTokenGGP")), "Cannot upgrade token contracts");
require(nameHash != keccak256(abi.encodePacked("gogoTokenGGPFixedSupply")), "Cannot upgrade token contracts");
// require(nameHash != keccak256(abi.encodePacked("casperDeposit")), "Cannot upgrade the casper deposit contract");
require(nameHash != keccak256(abi.encodePacked("rocketMinipoolPenalty")), "Cannot upgrade minipool penalty contract");
// Get old contract address & check contract exists
address oldContractAddress = getAddress(keccak256(abi.encodePacked("contract.address", _name)));
Expand Down
Loading