Skip to content

Commit

Permalink
v0.6.4 (#297)
Browse files Browse the repository at this point in the history
  • Loading branch information
nxqbao authored Oct 21, 2023
2 parents 63f1b56 + aa272d3 commit eb38695
Show file tree
Hide file tree
Showing 479 changed files with 84,881 additions and 17,255 deletions.
19 changes: 13 additions & 6 deletions .github/workflows/unittest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,35 @@ name: Run tests
on:
push:
branches:
- main
- dev
- mainnet
- testnet
- "release/**"
pull_request:
branches:
- main
- dev
- testnet
- "release/**"

permissions:
packages: read

concurrency:
group: ${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
nodejs:
runs-on: ubuntu-latest
steps:
- name: "Checkout Repo"
uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 #v3.0.2
with:
submodules: recursive

- name: "Setup Node"
uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 #v3.4.1
with:
node-version: v14.18.1
node-version: v16.16.0

- name: Github private package token in npmrc
run: |
Expand All @@ -38,6 +42,9 @@ jobs:
with:
cmd: install

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@cb603ca0abb544f301eaed59ac0baf579aa6aecf #v1.0.10

- name: "Run Compile"
uses: borales/actions-yarn@97ba8bebfe5b549bb7999261698a52a81fd62f1b #v4.2.0
with:
Expand All @@ -46,4 +53,4 @@ jobs:
- name: "Run Test"
uses: borales/actions-yarn@97ba8bebfe5b549bb7999261698a52a81fd62f1b #v4.2.0
with:
cmd: test
cmd: test:ci
9 changes: 8 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,12 @@ yarn-error.log
refs/
.vscode
remix-compiler.config.js
foundry
.npmrc
.yarn
.yarnrc.yml
logs/storage_layout_table.log
cache_foundry
out
.DS_Store

dry-run/
14 changes: 14 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "lib/prb-test"]
branch = release-v0
path = lib/prb-test
url = https://github.com/PaulRBerg/prb-test
[submodule "lib/prb-math"]
path = lib/prb-math
url = https://github.com/PaulRBerg/prb-math
branch = release-v4
[submodule "lib/solady"]
path = lib/solady
url = https://github.com/vectorized/solady
4 changes: 4 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@
set -ex

yarn lint-staged
yarn clean
yarn compile
yarn plugin:storage-layout --override true
git add logs/storage_layout.log
git add logs/contract_code_sizes.log
18 changes: 16 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ The collections of smart contracts that power the Ronin Delegated Proof of Stake
$ yarn --frozen-lockfile
```

- Install foundry libs

```
$ git submodule add -b release-v0 https://github.com/PaulRBerg/prb-test lib/prb-test
$ git submodule add -b release-v4 https://github.com/PaulRBerg/prb-math lib/prb-math
```
- Compile contracts
```shell
Expand All @@ -36,17 +43,24 @@ The collections of smart contracts that power the Ronin Delegated Proof of Stake
$ yarn test
```

- Extract storage layout
```shell
$ yarn plugin:storage-layout [--destination <output-path>] [--override <true|false>]
```
- `<output-path>` (optional): The path to store generated storage layout file. If not provided, the default path is `layout/storage.txt`.
- `--override` (optional): Indicates whether to override the destination file at `<output-path>` if it already exists. By default, it is set to `false`.

### Target chain to deploy

This repo contains source code of contracts that will be either deployed on the mainchains, or on Ronin chain.

- On mainchains:
- Governance contract: `MainchainGovernanceAdmin`
- Bridge contract: `MainchainGatewayV2`
- Bridge contract: `MainchainGatewayV3`
- Trusted orgs contract: `RoninTrustedOrganization`
- On Ronin chain:
- Governance contract: `RoninGovernanceAdmin`
- Bridge operation: `RoninGatewayV2`
- Bridge operation: `RoninGatewayV3`
- Trusted orgs contract: `RoninTrustedOrganization`
- DPoS contracts

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import "@openzeppelin/contracts/security/Pausable.sol";
import "../interfaces/IQuorum.sol";
import "./collections/HasProxyAdmin.sol";

abstract contract GatewayV2 is HasProxyAdmin, Pausable, IQuorum {
abstract contract GatewayV3 is HasProxyAdmin, Pausable, IQuorum {
uint256 internal _num;
uint256 internal _denom;

Expand Down Expand Up @@ -44,28 +44,26 @@ abstract contract GatewayV2 is HasProxyAdmin, Pausable, IQuorum {
/**
* @inheritdoc IQuorum
*/
function setThreshold(uint256 _numerator, uint256 _denominator)
external
virtual
onlyAdmin
returns (uint256, uint256)
{
function setThreshold(
uint256 _numerator,
uint256 _denominator
) external virtual onlyAdmin returns (uint256, uint256) {
return _setThreshold(_numerator, _denominator);
}

/**
* @dev Triggers paused state.
*/
function pause() external {
require(msg.sender == _getAdmin() || msg.sender == emergencyPauser, "GatewayV2: not authorized pauser");
_requireAuth();
_pause();
}

/**
* @dev Triggers unpaused state.
*/
function unpause() external {
require(msg.sender == _getAdmin() || msg.sender == emergencyPauser, "GatewayV2: not authorized pauser");
_requireAuth();
_unpause();
}

Expand All @@ -82,17 +80,18 @@ abstract contract GatewayV2 is HasProxyAdmin, Pausable, IQuorum {
* Emits the `ThresholdUpdated` event.
*
*/
function _setThreshold(uint256 _numerator, uint256 _denominator)
internal
virtual
returns (uint256 _previousNum, uint256 _previousDenom)
{
require(_numerator <= _denominator, "GatewayV2: invalid threshold");
function _setThreshold(
uint256 _numerator,
uint256 _denominator
) internal virtual returns (uint256 _previousNum, uint256 _previousDenom) {
if (_numerator > _denominator) revert ErrInvalidThreshold(msg.sig);
_previousNum = _num;
_previousDenom = _denom;
_num = _numerator;
_denom = _denominator;
emit ThresholdUpdated(nonce++, _numerator, _denominator, _previousNum, _previousDenom);
unchecked {
emit ThresholdUpdated(nonce++, _numerator, _denominator, _previousNum, _previousDenom);
}
}

/**
Expand All @@ -102,6 +101,20 @@ abstract contract GatewayV2 is HasProxyAdmin, Pausable, IQuorum {
return (_num * _totalWeight + _denom - 1) / _denom;
}

/**
* @dev Internal method to check method caller.
*
* Requirements:
*
* - The method caller must be admin or pauser.
*
*/
function _requireAuth() private view {
if (!(msg.sender == _getAdmin() || msg.sender == emergencyPauser)) {
revert ErrUnauthorized(msg.sig, RoleAccess.ADMIN);
}
}

/**
* @dev Returns the total weight.
*/
Expand Down
100 changes: 54 additions & 46 deletions contracts/extensions/GovernanceAdmin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,63 @@
pragma solidity ^0.8.0;

import "../extensions/sequential-governance/CoreGovernance.sol";
import "../extensions/collections/HasRoninTrustedOrganizationContract.sol";
import "../extensions/collections/HasBridgeContract.sol";
import "../extensions/collections/HasContracts.sol";
import "../interfaces/IRoninTrustedOrganization.sol";
import { ErrorHandler } from "../libraries/ErrorHandler.sol";
import { IdentityGuard } from "../utils/IdentityGuard.sol";
import { HasGovernanceAdminDeprecated, HasBridgeDeprecated } from "../utils/DeprecatedSlots.sol";

abstract contract GovernanceAdmin is
CoreGovernance,
IdentityGuard,
HasContracts,
HasGovernanceAdminDeprecated,
HasBridgeDeprecated
{
using ErrorHandler for bool;

abstract contract GovernanceAdmin is CoreGovernance, HasRoninTrustedOrganizationContract, HasBridgeContract {
uint256 public roninChainId;
/// @dev Domain separator
bytes32 public DOMAIN_SEPARATOR;

error ErrProxyCallFailed(bytes4 methodSignature);
constructor(uint256 _roninChainId, address _roninTrustedOrganizationContract) {
roninChainId = _roninChainId;

modifier onlySelfCall() {
require(msg.sender == address(this), "GovernanceAdmin: only allowed self-call");
_;
}
/*
* DOMAIN_SEPARATOR = keccak256(
* abi.encode(
* keccak256("EIP712Domain(string name,string version,bytes32 salt)"),
* keccak256("GovernanceAdmin"), // name hash
* keccak256("2"), // version hash
* keccak256(abi.encode("RONIN_GOVERNANCE_ADMIN", _roninChainId)) // salt
* )
*/
assembly {
let ptr := mload(0x40)

constructor(
uint256 _roninChainId,
address _roninTrustedOrganizationContract,
address _bridgeContract,
uint256 _proposalExpiryDuration
) CoreGovernance(_proposalExpiryDuration) {
roninChainId = _roninChainId;
DOMAIN_SEPARATOR = keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,bytes32 salt)"),
keccak256("GovernanceAdmin"), // name hash
keccak256("2"), // version hash
keccak256(abi.encode("RONIN_GOVERNANCE_ADMIN", _roninChainId)) // salt
)
);
_setRoninTrustedOrganizationContract(_roninTrustedOrganizationContract);
_setBridgeContract(_bridgeContract);
}
// See abi.encode implementation: https://github.com/axieinfinity/ronin/blob/569ebd5a782da5601c6aba22799dc9b4afd39da9/accounts/abi/argument.go#L227-L267
mstore(ptr, 0x40) // offset bytes
mstore(add(ptr, 0x20), _roninChainId)
mstore(add(ptr, 0x40), 0x16) // "RONIN_GOVERNANCE_ADMIN".length
mstore(add(ptr, 0x60), 0x524f4e494e5f474f5645524e414e43455f41444d494e00000000000000000000) // bytes("RONIN_GOVERNANCE_ADMIN")
let salt := keccak256(ptr, 0x80) // keccak256(abi.encode("RONIN_GOVERNANCE_ADMIN", _roninChainId))

/**
* @inheritdoc IHasRoninTrustedOrganizationContract
*/
function setRoninTrustedOrganizationContract(address _addr) external override onlySelfCall {
require(_addr.code.length > 0, "GovernanceAdmin: set to non-contract");
_setRoninTrustedOrganizationContract(_addr);
mstore(ptr, 0x599a80fcaa47b95e2323ab4d34d34e0cc9feda4b843edafcc30c7bdf60ea15bf) // keccak256("EIP712Domain(string name,string version,bytes32 salt)")
mstore(add(ptr, 0x20), 0x7e7935007966eb860f4a2ee3dcc9fd53fb3205ce2aa86b0126d4893d4d4c14b9) // keccak256("GovernanceAdmin")
mstore(add(ptr, 0x40), 0x2a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4de) // keccak256("3")
mstore(add(ptr, 0x60), salt)
sstore(DOMAIN_SEPARATOR.slot, keccak256(ptr, 0x80))
}

_setContract(ContractType.RONIN_TRUSTED_ORGANIZATION, _roninTrustedOrganizationContract);
}

/**
* @inheritdoc IHasBridgeContract
* @inheritdoc IHasContracts
*/
function setBridgeContract(address _addr) external override onlySelfCall {
require(_addr.code.length > 0, "GovernanceAdmin: set to non-contract");
_setBridgeContract(_addr);
function setContract(ContractType contractType, address addr) external virtual override onlySelfCall {
_requireHasCode(addr);
_setContract(contractType, addr);
}

/**
Expand All @@ -76,7 +84,7 @@ abstract contract GovernanceAdmin is CoreGovernance, HasRoninTrustedOrganization
// bytes4(keccak256("implementation()")) == 0x5c60da1b
bytes4 _selector = 0x5c60da1b;
(bool _success, bytes memory _returndata) = _proxy.staticcall(abi.encodeWithSelector(_selector));
if (!_success) revert ErrProxyCallFailed(_selector);
_success.handleRevert(_selector, _returndata);
return abi.decode(_returndata, (address));
}

Expand All @@ -99,7 +107,7 @@ abstract contract GovernanceAdmin is CoreGovernance, HasRoninTrustedOrganization
// bytes4(keccak256("admin()")) == 0xf851a440
bytes4 _selector = 0xf851a440;
(bool _success, bytes memory _returndata) = _proxy.staticcall(abi.encodeWithSelector(_selector));
if (!_success) revert ErrProxyCallFailed(_selector);
_success.handleRevert(_selector, _returndata);
return abi.decode(_returndata, (address));
}

Expand All @@ -113,39 +121,39 @@ abstract contract GovernanceAdmin is CoreGovernance, HasRoninTrustedOrganization
function changeProxyAdmin(address _proxy, address _newAdmin) external onlySelfCall {
// bytes4(keccak256("changeAdmin(address)"))
bytes4 _selector = 0x8f283970;
(bool _success, ) = _proxy.call(abi.encodeWithSelector(_selector, _newAdmin));
if (!_success) revert ErrProxyCallFailed(_selector);
(bool _success, bytes memory _returndata) = _proxy.call(abi.encodeWithSelector(_selector, _newAdmin));
_success.handleRevert(_selector, _returndata);
}

/**
* @dev Override `CoreGovernance-_getMinimumVoteWeight`.
*/
function _getMinimumVoteWeight() internal view virtual override returns (uint256) {
bytes4 _selector = IQuorum.minimumVoteWeight.selector;
(bool _success, bytes memory _returndata) = roninTrustedOrganizationContract().staticcall(
(bool _success, bytes memory _returndata) = getContract(ContractType.RONIN_TRUSTED_ORGANIZATION).staticcall(
abi.encodeWithSelector(
// TransparentUpgradeableProxyV2.functionDelegateCall.selector,
0x4bb5274a,
abi.encodeWithSelector(_selector)
)
);
if (!_success) revert ErrProxyCallFailed(_selector);
_success.handleRevert(_selector, _returndata);
return abi.decode(_returndata, (uint256));
}

/**
* @dev Override `CoreGovernance-_getTotalWeights`.
*/
function _getTotalWeights() internal view virtual override returns (uint256) {
bytes4 _selector = IRoninTrustedOrganization.totalWeights.selector;
(bool _success, bytes memory _returndata) = roninTrustedOrganizationContract().staticcall(
function _getTotalWeight() internal view virtual override returns (uint256) {
bytes4 _selector = IRoninTrustedOrganization.totalWeight.selector;
(bool _success, bytes memory _returndata) = getContract(ContractType.RONIN_TRUSTED_ORGANIZATION).staticcall(
abi.encodeWithSelector(
// TransparentUpgradeableProxyV2.functionDelegateCall.selector,
0x4bb5274a,
abi.encodeWithSelector(_selector)
)
);
if (!_success) revert ErrProxyCallFailed(_selector);
_success.handleRevert(_selector, _returndata);
return abi.decode(_returndata, (uint256));
}
}
Loading

0 comments on commit eb38695

Please sign in to comment.