Skip to content

Commit

Permalink
Merge pull request ubiquity#779 from Keyrxng/core-uups
Browse files Browse the repository at this point in the history
Core UUPS
  • Loading branch information
rndquu authored Sep 21, 2023
2 parents f99a1ee + 05c10ac commit 919c455
Show file tree
Hide file tree
Showing 40 changed files with 2,287 additions and 903 deletions.
5 changes: 4 additions & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,7 @@
path = packages/contracts/lib/Uniswap/v3-periphery
url = https://github.com/Uniswap/v3-periphery.git
branch= main

[submodule "packages/contracts/lib/openzeppelin-contracts-upgradeable"]
path = packages/contracts/lib/openzeppelin-contracts-upgradeable
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
branch = release-v4.9
4 changes: 3 additions & 1 deletion cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,9 @@
"Txpool",
"nomicfoundation",
"blockhash",
"Merkle"
"Merkle",
"UUPS",
"Initializable"
],
"flagWords": ["creditNFT", "CreditNFT"],
"language": "en-US"
Expand Down
1,567 changes: 975 additions & 592 deletions packages/contracts/broadcast/05_StakingShare.s.sol/31337/run-latest.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions packages/contracts/lib/openzeppelin-contracts-upgradeable
2 changes: 1 addition & 1 deletion packages/contracts/lib/solidity-linked-list
1 change: 1 addition & 0 deletions packages/contracts/remappings.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts
@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts
forge-std/=lib/forge-std/src/
ds-test/=lib/forge-std/lib/ds-test/src/
solidity-linked-list/=lib/solidity-linked-list
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,35 @@
pragma solidity 0.8.19;

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";

import "./01_Diamond.s.sol";

contract DollarScript is DiamondScript {
UbiquityDollarToken dollar;
address metapool;

UbiquityDollarToken public dollarToken;
ERC1967Proxy public proxyDollarToken;

function run() public virtual override {
super.run();
vm.startBroadcast(deployerPrivateKey);
bytes memory managerPayload = abi.encodeWithSignature(
"initialize(address)",
address(diamond)
);

proxyDollarToken = new ERC1967Proxy(
address(new UbiquityDollarToken()),
managerPayload
);
dollarToken = UbiquityDollarToken(address(proxyDollarToken));

dollar = new UbiquityDollarToken(address(diamond));
IManager.setDollarTokenAddress(address(dollar));
IManager.setDollarTokenAddress(address(dollarToken));
IAccessControl.grantRole(DOLLAR_TOKEN_MINTER_ROLE, address(diamond));
IAccessControl.grantRole(DOLLAR_TOKEN_BURNER_ROLE, address(diamond));

dollar.mint(address(diamond), 10000e18);
dollarToken.mint(address(diamond), 10000e18);
uint256 adminBal = IERC20(curve3PoolToken).balanceOf(admin);
console.log("----ADMIN 3CRV bal:", adminBal);
// deployer needs 10000 3CRV to deploy the pool
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,36 @@ pragma solidity 0.8.19;
import "./02_UbiquityDollarToken.s.sol";

contract GovernanceScript is DollarScript {
UbiquityGovernanceToken governance;
UbiquityGovernanceToken public governanceToken;
ERC1967Proxy public proxyGovernanceToken;

function run() public virtual override {
super.run();
vm.startBroadcast(deployerPrivateKey);

governance = new UbiquityGovernanceToken(address(diamond));
bytes memory managerPayload = abi.encodeWithSignature(
"initialize(address)",
address(diamond)
);

IManager.setGovernanceTokenAddress(address(governance));
proxyGovernanceToken = new ERC1967Proxy(
address(new UbiquityGovernanceToken()),
managerPayload
);
governanceToken = UbiquityGovernanceToken(
address(proxyGovernanceToken)
);

IManager.setGovernanceTokenAddress(address(governanceToken));
// grant diamond token admin rights
IAccessControl.grantRole(GOVERNANCE_TOKEN_MINTER_ROLE, address(diamond));
IAccessControl.grantRole(GOVERNANCE_TOKEN_BURNER_ROLE, address(diamond));
IAccessControl.grantRole(
GOVERNANCE_TOKEN_MINTER_ROLE,
address(diamond)
);
IAccessControl.grantRole(
GOVERNANCE_TOKEN_BURNER_ROLE,
address(diamond)
);

vm.stopBroadcast();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,38 @@ import {UbiquityCreditToken} from "../../../../src/dollar/core/UbiquityCreditTok
import {CreditNft} from "../../../../src/dollar/core/CreditNft.sol";

contract CreditScript is GovernanceScript {
UbiquityCreditToken public creditToken;
CreditNft public creditNft;

ERC1967Proxy public proxyCreditToken;
ERC1967Proxy public proxyCreditNft;

function run() public virtual override {
super.run();
vm.startBroadcast(deployerPrivateKey);
bytes memory managerPayload = abi.encodeWithSignature(
"initialize(address)",
address(diamond)
);

UbiquityCreditToken credit = new UbiquityCreditToken(address(diamond));
IManager.setCreditTokenAddress(address(credit));
proxyCreditToken = new ERC1967Proxy(
address(new UbiquityCreditToken()),
managerPayload
);
creditToken = UbiquityCreditToken(address(proxyCreditToken));

IManager.setCreditTokenAddress(address(creditToken));

IAccessControl.grantRole(CREDIT_TOKEN_MINTER_ROLE, address(diamond));
IAccessControl.grantRole(CREDIT_TOKEN_BURNER_ROLE, address(diamond));
IAccessControl.grantRole(CREDIT_NFT_MANAGER_ROLE, address(diamond));

CreditNft creditNft = new CreditNft(address(diamond));
proxyCreditNft = new ERC1967Proxy(
address(new CreditNft()),
managerPayload
);
creditNft = CreditNft(address(proxyCreditNft));

IManager.setCreditNftAddress(address(creditNft));

vm.stopBroadcast();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ pragma solidity 0.8.19;
import "./04_UbiquityCredit.s.sol";

contract StakingShareScript is CreditScript {
StakingShare public stakingShare;
ERC1967Proxy public proxyStakingShare;

function run() public virtual override {
super.run();
vm.startBroadcast(deployerPrivateKey);
Expand All @@ -13,11 +16,19 @@ contract StakingShareScript is CreditScript {
// add staking shares
string
memory uri = "https://bafybeifibz4fhk4yag5reupmgh5cdbm2oladke4zfd7ldyw7avgipocpmy.ipfs.infura-ipfs.io/";

address stakingShareAddress = address(
new StakingShare(address(diamond), uri)
bytes memory initData = abi.encodeWithSignature(
"initialize(address,string)",
address(diamond),
uri
);
proxyStakingShare = new ERC1967Proxy(
address(new StakingShare()),
initData
);
IManager.setStakingShareAddress(stakingShareAddress);

stakingShare = StakingShare(address(proxyStakingShare));

IManager.setStakingShareAddress(address(stakingShare));

vm.stopBroadcast();
}
Expand Down
27 changes: 19 additions & 8 deletions packages/contracts/src/dollar/core/CreditNft.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
pragma solidity 0.8.19;

import {ERC1155Ubiquity} from "./ERC1155Ubiquity.sol";
import "solidity-linked-list/contracts/StructuredLinkedList.sol";
import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import {ERC1155Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol";
import {ICreditNft} from "../../dollar/interfaces/ICreditNft.sol";
import "solidity-linked-list/contracts/StructuredLinkedList.sol";
import "../libraries/Constants.sol";

/**
Expand Down Expand Up @@ -44,18 +46,21 @@ contract CreditNft is ERC1155Ubiquity, ICreditNft {
/// @notice Modifier checks that the method is called by a user with the "CreditNft manager" role
modifier onlyCreditNftManager() {
require(
accessControl.hasRole(CREDIT_NFT_MANAGER_ROLE, msg.sender),
accessControl.hasRole(CREDIT_NFT_MANAGER_ROLE, _msgSender()),
"Caller is not a CreditNft manager"
);
_;
}

/**
* @notice Contract constructor
* @dev URI param is if we want to add an off-chain meta data uri associated with this contract
* @param _manager Access control address
*/
constructor(address _manager) ERC1155Ubiquity(_manager, "URI") {
/// @notice Ensures initialize cannot be called on the implementation contract
constructor() {
_disableInitializers();
}

/// @notice Initializes the contract
/// @param _manager Address of the manager of the contract
function initialize(address _manager) public initializer {
__ERC1155Ubiquity_init(_manager, "URI");
_totalOutstandingDebt = 0;
}

Expand Down Expand Up @@ -159,4 +164,10 @@ contract CreditNft is ERC1155Ubiquity, ICreditNft {

return outstandingDebt;
}

/// @notice Allows an admin to upgrade to another implementation contract
/// @param newImplementation Address of the new implementation contract
function _authorizeUpgrade(
address newImplementation
) internal override(ERC1155Ubiquity) onlyAdmin {}
}
70 changes: 55 additions & 15 deletions packages/contracts/src/dollar/core/ERC1155Ubiquity.sol
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Burnable.sol";
import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Pausable.sol";
import {ERC1155Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol";
import {ERC1155BurnableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol";
import {ERC1155PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155PausableUpgradeable.sol";
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "../interfaces/IAccessControl.sol";
import "../libraries/Constants.sol";

Expand All @@ -16,7 +18,12 @@ import "../../../src/dollar/utils/SafeAddArray.sol";
* - TotalSupply per id
* - Ubiquity Manager access control
*/
contract ERC1155Ubiquity is ERC1155, ERC1155Burnable, ERC1155Pausable {
contract ERC1155Ubiquity is
Initializable,
ERC1155BurnableUpgradeable,
ERC1155PausableUpgradeable,
UUPSUpgradeable
{
using SafeAddArray for uint256[];

/// @notice Access control interface
Expand All @@ -33,7 +40,7 @@ contract ERC1155Ubiquity is ERC1155, ERC1155Burnable, ERC1155Pausable {
/// @notice Modifier checks that the method is called by a user with the "Governance minter" role
modifier onlyMinter() virtual {
require(
accessControl.hasRole(GOVERNANCE_TOKEN_MINTER_ROLE, msg.sender),
accessControl.hasRole(GOVERNANCE_TOKEN_MINTER_ROLE, _msgSender()),
"ERC1155Ubiquity: not minter"
);
_;
Expand All @@ -42,7 +49,7 @@ contract ERC1155Ubiquity is ERC1155, ERC1155Burnable, ERC1155Pausable {
/// @notice Modifier checks that the method is called by a user with the "Governance burner" role
modifier onlyBurner() virtual {
require(
accessControl.hasRole(GOVERNANCE_TOKEN_BURNER_ROLE, msg.sender),
accessControl.hasRole(GOVERNANCE_TOKEN_BURNER_ROLE, _msgSender()),
"ERC1155Ubiquity: not burner"
);
_;
Expand All @@ -51,7 +58,7 @@ contract ERC1155Ubiquity is ERC1155, ERC1155Burnable, ERC1155Pausable {
/// @notice Modifier checks that the method is called by a user with the "Pauser" role
modifier onlyPauser() virtual {
require(
accessControl.hasRole(PAUSER_ROLE, msg.sender),
accessControl.hasRole(PAUSER_ROLE, _msgSender()),
"ERC1155Ubiquity: not pauser"
);
_;
Expand All @@ -60,18 +67,38 @@ contract ERC1155Ubiquity is ERC1155, ERC1155Burnable, ERC1155Pausable {
/// @notice Modifier checks that the method is called by a user with the "Admin" role
modifier onlyAdmin() {
require(
accessControl.hasRole(DEFAULT_ADMIN_ROLE, msg.sender),
accessControl.hasRole(DEFAULT_ADMIN_ROLE, _msgSender()),
"ERC20Ubiquity: not admin"
);
_;
}

/**
* @notice Contract constructor
* @param _manager Access control address
* @param uri Base URI
*/
constructor(address _manager, string memory uri) ERC1155(uri) {
/// @notice Ensures __ERC1155Ubiquity_init cannot be called on the implementation contract
constructor() {
_disableInitializers();
}

/// @notice Initializes this contract with all base(parent) contracts
/// @param _manager Address of the manager of the contract
/// @param _uri Base URI
function __ERC1155Ubiquity_init(
address _manager,
string memory _uri
) public initializer onlyInitializing {
// init base contracts
__ERC1155_init(_uri);
__ERC1155Burnable_init();
__ERC1155Pausable_init();
__UUPSUpgradeable_init();
// init current contract
__ERC1155Ubiquity_init_unchained(_manager);
}

/// @notice Initializes the current contract
/// @param _manager Address of the manager of the contract
function __ERC1155Ubiquity_init_unchained(
address _manager
) public initializer onlyInitializing {
accessControl = IAccessControl(_manager);
}

Expand Down Expand Up @@ -270,7 +297,20 @@ contract ERC1155Ubiquity is ERC1155, ERC1155Burnable, ERC1155Pausable {
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual override(ERC1155, ERC1155Pausable) {
)
internal
virtual
override(ERC1155PausableUpgradeable, ERC1155Upgradeable)
{
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
}

/// @notice Allows an admin to upgrade to another implementation contract
/// @param newImplementation Address of the new implementation contract
function _authorizeUpgrade(
address newImplementation
) internal virtual override onlyAdmin {}

/// @notice Allows for future upgrades on the base contract without affecting the storage of the derived contract
uint256[50] private __gap;
}
Loading

0 comments on commit 919c455

Please sign in to comment.