diff --git a/contracts/terminus/LibTerminus.sol b/contracts/terminus/LibTerminus.sol index e6ff041..ce534e5 100644 --- a/contracts/terminus/LibTerminus.sol +++ b/contracts/terminus/LibTerminus.sol @@ -35,6 +35,8 @@ library LibTerminus { mapping(uint256 => bool) poolBurnable; mapping(address => mapping(address => bool)) globalOperatorApprovals; mapping(uint256 => mapping(address => bool)) globalPoolOperatorApprovals; + // Contract metadata + string contractURI; } function terminusStorage() diff --git a/contracts/terminus/TerminusFacet.sol b/contracts/terminus/TerminusFacet.sol index 965dae7..7c74f4e 100644 --- a/contracts/terminus/TerminusFacet.sol +++ b/contracts/terminus/TerminusFacet.sol @@ -122,6 +122,16 @@ contract TerminusFacet is ERC1155WithTerminusStorage { paymentTokenContract.transfer(toAddress, amount); } + function contractURI() public view returns (string memory) { + return LibTerminus.terminusStorage().contractURI; + } + + function setContractURI(string memory _contractURI) external { + LibTerminus.enforceIsController(); + LibTerminus.TerminusStorage storage ts = LibTerminus.terminusStorage(); + ts.contractURI = _contractURI; + } + function setURI(uint256 poolID, string memory poolURI) external { LibTerminus.enforcePoolIsController(poolID, _msgSender()); LibTerminus.TerminusStorage storage ts = LibTerminus.terminusStorage(); diff --git a/dao/TerminusFacet.py b/dao/TerminusFacet.py index 303fb01..a7ba33a 100644 --- a/dao/TerminusFacet.py +++ b/dao/TerminusFacet.py @@ -115,6 +115,10 @@ class TerminusFacet: self.assert_contract_is_instantiated() return self.contract.burn(from_, pool_id, amount, transaction_config) + def contract_uri(self) -> Any: + self.assert_contract_is_instantiated() + return self.contract.contractURI.call() + def create_pool_v1( self, _capacity: int, _transferable: bool, _burnable: bool, transaction_config ) -> Any: @@ -209,6 +213,10 @@ class TerminusFacet: self.assert_contract_is_instantiated() return self.contract.setApprovalForAll(operator, approved, transaction_config) + def set_contract_uri(self, _contract_uri: str, transaction_config) -> Any: + self.assert_contract_is_instantiated() + return self.contract.setContractURI(_contract_uri, transaction_config) + def set_payment_token( self, new_payment_token: ChecksumAddress, transaction_config ) -> Any: @@ -363,6 +371,13 @@ def handle_burn(args: argparse.Namespace) -> None: print(result) +def handle_contract_uri(args: argparse.Namespace) -> None: + network.connect(args.network) + contract = TerminusFacet(args.address) + result = contract.contract_uri() + print(result) + + def handle_create_pool_v1(args: argparse.Namespace) -> None: network.connect(args.network) contract = TerminusFacet(args.address) @@ -497,6 +512,16 @@ def handle_set_approval_for_all(args: argparse.Namespace) -> None: print(result) +def handle_set_contract_uri(args: argparse.Namespace) -> None: + network.connect(args.network) + contract = TerminusFacet(args.address) + transaction_config = get_transaction_config(args) + result = contract.set_contract_uri( + _contract_uri=args.contract_uri_arg, transaction_config=transaction_config + ) + print(result) + + def handle_set_payment_token(args: argparse.Namespace) -> None: network.connect(args.network) contract = TerminusFacet(args.address) @@ -650,6 +675,10 @@ def generate_cli() -> argparse.ArgumentParser: burn_parser.add_argument("--amount", required=True, help="Type: uint256", type=int) burn_parser.set_defaults(func=handle_burn) + contract_uri_parser = subcommands.add_parser("contract-uri") + add_default_arguments(contract_uri_parser, False) + contract_uri_parser.set_defaults(func=handle_contract_uri) + create_pool_v1_parser = subcommands.add_parser("create-pool-v1") add_default_arguments(create_pool_v1_parser, True) create_pool_v1_parser.add_argument( @@ -784,6 +813,13 @@ def generate_cli() -> argparse.ArgumentParser: ) set_approval_for_all_parser.set_defaults(func=handle_set_approval_for_all) + set_contract_uri_parser = subcommands.add_parser("set-contract-uri") + add_default_arguments(set_contract_uri_parser, True) + set_contract_uri_parser.add_argument( + "--contract-uri-arg", required=True, help="Type: string", type=str + ) + set_contract_uri_parser.set_defaults(func=handle_set_contract_uri) + set_payment_token_parser = subcommands.add_parser("set-payment-token") add_default_arguments(set_payment_token_parser, True) set_payment_token_parser.add_argument( diff --git a/dao/test_terminus.py b/dao/test_terminus.py index 6888801..7274db6 100644 --- a/dao/test_terminus.py +++ b/dao/test_terminus.py @@ -32,6 +32,20 @@ class TestDeployment(MoonstreamDAOSingleContractTestCase): self.assertEqual(controller, accounts[0].address) +class TestContractURI(TerminusTestCase): + def test_contract_uri(self): + terminus_diamond_address = self.terminus_contracts["Diamond"] + diamond_terminus = TerminusFacet.TerminusFacet(terminus_diamond_address) + + contract_uri = diamond_terminus.contract_uri() + self.assertEqual(contract_uri, "") + + diamond_terminus.set_contract_uri("https://example.com", {"from": accounts[0]}) + + contract_uri = diamond_terminus.contract_uri() + self.assertEqual(contract_uri, "https://example.com") + + class TestPoolCreation(TerminusTestCase): def test_create_simple_pool(self): moonstream_diamond_address = self.contracts["Diamond"] diff --git a/operations/terminus-update-mainnet-20220125-0637.md b/operations/terminus-update-mainnet-20220125-0637.md new file mode 100644 index 0000000..bafd657 --- /dev/null +++ b/operations/terminus-update-mainnet-20220125-0637.md @@ -0,0 +1,72 @@ +# Update the Terminus contract + +The Terminus contract is deployed as an EIP2535 Diamond proxy contract with a Terminus facet attached to it. + +This checklist describes how to update the `TerminusFacet` on the Terminus diamond contract. + +## Deployed addresses + +You will modify this section as you go through the checklist + + +### `TerminusFacet` address + +``` +export TERMINUS_FACET_ADDRESS="0x9718FA06867D2939981151D193cF7ee2B924aec0" +``` + +## Environment variables + +- [x] `export DAO_NETWORK=matic` +- [x] `export DAO_OWNER=` +- [x] `export DAO_OWNER_ADDRESS=$(jq -r .address $DAO_OWNER)` +- [x] `export GAS_PRICE="300 gwei"` +- [x] `export CONFIRMATIONS=5` +- [x] `export TERMINUS_DIAMOND=0x062BEc5e84289Da2CD6147E0e4DA402B33B8f796` + +## Detach existing `TerminusFacet` + +- [x] Remove `TerminusFacet` from diamond. (This may require checkout of earlier commit and `brownie compile`. Checked out: `v0.0.1`.) + +```bash +dao core facet-cut \ + --address $TERMINUS_DIAMOND \ + --network $DAO_NETWORK \ + --sender $DAO_OWNER \ + --gas-price "$GAS_PRICE" \ + --confirmations $CONFIRMATIONS \ + --facet-name TerminusFacet \ + --action remove \ + --ignore-methods contractURI setContractURI +``` + + +## Deploy `TerminusFacet` + +- [x] Deploy `TerminusFacet` contract + +```bash +dao terminus deploy \ + --network $DAO_NETWORK \ + --sender $DAO_OWNER \ + --gas-price "$GAS_PRICE" \ + --confirmations $CONFIRMATIONS +``` + +- [x] Export address of deployed contract as `export TERMINUS_FACET_ADDRESS=0x9718FA06867D2939981151D193cF7ee2B924aec0` + +- [x] Store address of deployed contract under `Deployed addresses / TerminusFacet address` above + +- [x] Attach `TerminusFacet` to diamond: + +```bash +dao core facet-cut \ + --address $TERMINUS_DIAMOND \ + --network $DAO_NETWORK \ + --sender $DAO_OWNER \ + --gas-price "$GAS_PRICE" \ + --confirmations $CONFIRMATIONS \ + --facet-name TerminusFacet \ + --facet-address $TERMINUS_FACET_ADDRESS \ + --action add +``` diff --git a/operations/terminus-update-mumbai-20220125-0637.md b/operations/terminus-update-mumbai-20220125-0637.md new file mode 100644 index 0000000..a6d5644 --- /dev/null +++ b/operations/terminus-update-mumbai-20220125-0637.md @@ -0,0 +1,72 @@ +# Update the Terminus contract + +The Terminus contract is deployed as an EIP2535 Diamond proxy contract with a Terminus facet attached to it. + +This checklist describes how to update the `TerminusFacet` on the Terminus diamond contract. + +## Deployed addresses + +You will modify this section as you go through the checklist + + +### `TerminusFacet` address + +``` +export TERMINUS_FACET_ADDRESS="0x1Ea387841A8094018E995E112cad4B88e17862bA" +``` + +## Environment variables + +- [x] `export DAO_NETWORK=polygon-test` +- [x] `export DAO_OWNER=.secrets/dao-dev.json` +- [x] `export DAO_OWNER_ADDRESS=$(jq -r .address $DAO_OWNER)` +- [x] `export GAS_PRICE="35 gwei"` +- [x] `export CONFIRMATIONS=2` +- [x] `export TERMINUS_DIAMOND=0x040Cf7Ee9752936d8d280062a447eB53808EBc08` + +## Detach existing `TerminusFacet` + +- [x] Remove `TerminusFacet` from diamond. (This may require checkout of earlier commit and `brownie compile`. Checked out: `v0.0.1`.) + +```bash +dao core facet-cut \ + --address $TERMINUS_DIAMOND \ + --network $DAO_NETWORK \ + --sender $DAO_OWNER \ + --gas-price "$GAS_PRICE" \ + --confirmations $CONFIRMATIONS \ + --facet-name TerminusFacet \ + --action remove \ + --ignore-methods contractURI setContractURI +``` + + +## Deploy `TerminusFacet` + +- [x] Deploy `TerminusFacet` contract + +```bash +dao terminus deploy \ + --network $DAO_NETWORK \ + --sender $DAO_OWNER \ + --gas-price "$GAS_PRICE" \ + --confirmations $CONFIRMATIONS +``` + +- [x] Export address of deployed contract as `export TERMINUS_FACET_ADDRESS=0x1Ea387841A8094018E995E112cad4B88e17862bA` + +- [x] Store address of deployed contract under `Deployed addresses / TerminusFacet address` above + +- [x] Attach `TerminusFacet` to diamond: + +```bash +dao core facet-cut \ + --address $TERMINUS_DIAMOND \ + --network $DAO_NETWORK \ + --sender $DAO_OWNER \ + --gas-price "$GAS_PRICE" \ + --confirmations $CONFIRMATIONS \ + --facet-name TerminusFacet \ + --facet-address $TERMINUS_FACET_ADDRESS \ + --action add +```