From 6ad179f452aa3aee0262d48e77fa54e66e229c35 Mon Sep 17 00:00:00 2001 From: Neeraj Kashyap Date: Sun, 19 Dec 2021 05:07:21 -0800 Subject: [PATCH] Added payment functionality to Terminus --- contracts/terminus/TerminusFacet.sol | 20 +++++++ dao/TerminusFacet.py | 64 ++++++++++++++++++++++ dao/test_core.py | 2 +- dao/test_terminus.py | 80 ++++++++++++++++++++++++++-- 4 files changed, 160 insertions(+), 6 deletions(-) diff --git a/contracts/terminus/TerminusFacet.sol b/contracts/terminus/TerminusFacet.sol index eee9dc8..6cde104 100644 --- a/contracts/terminus/TerminusFacet.sol +++ b/contracts/terminus/TerminusFacet.sol @@ -31,6 +31,16 @@ contract TerminusFacet is ERC1155WithTerminusStorage { ts.paymentToken = newPaymentToken; } + function poolBasePrice() external view returns (uint256) { + return LibTerminus.terminusStorage().poolBasePrice; + } + + function setPoolBasePrice(uint256 newBasePrice) external { + LibTerminus.enforceIsController(); + LibTerminus.TerminusStorage storage ts = LibTerminus.terminusStorage(); + ts.poolBasePrice = newBasePrice; + } + function _paymentTokenContract() internal view returns (IERC20) { address paymentTokenAddress = LibTerminus .terminusStorage() @@ -42,6 +52,16 @@ contract TerminusFacet is ERC1155WithTerminusStorage { return IERC20(paymentTokenAddress); } + function withdrawPayments(address toAddress, uint256 amount) external { + LibTerminus.enforceIsController(); + require( + _msgSender() == toAddress, + "TerminusFacet: withdrawPayments -- Controller can only withdraw to self" + ); + IERC20 paymentTokenContract = _paymentTokenContract(); + paymentTokenContract.transfer(toAddress, amount); + } + 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 8eb56fa..9efb786 100644 --- a/dao/TerminusFacet.py +++ b/dao/TerminusFacet.py @@ -134,6 +134,10 @@ class TerminusFacet: self.assert_contract_is_instantiated() return self.contract.paymentToken.call() + def pool_base_price(self) -> Any: + self.assert_contract_is_instantiated() + return self.contract.poolBasePrice.call() + def safe_batch_transfer_from( self, from_: ChecksumAddress, @@ -174,6 +178,10 @@ class TerminusFacet: self.assert_contract_is_instantiated() return self.contract.setPaymentToken(new_payment_token, transaction_config) + def set_pool_base_price(self, new_base_price: int, transaction_config) -> Any: + self.assert_contract_is_instantiated() + return self.contract.setPoolBasePrice(new_base_price, transaction_config) + def set_uri(self, pool_id: int, pool_uri: str, transaction_config) -> Any: self.assert_contract_is_instantiated() return self.contract.setURI(pool_id, pool_uri, transaction_config) @@ -198,6 +206,12 @@ class TerminusFacet: self.assert_contract_is_instantiated() return self.contract.uri.call(pool_id) + def withdraw_payments( + self, to_address: ChecksumAddress, amount: int, transaction_config + ) -> Any: + self.assert_contract_is_instantiated() + return self.contract.withdrawPayments(to_address, amount, transaction_config) + def get_transaction_config(args: argparse.Namespace) -> Dict[str, Any]: signer = network.accounts.load(args.sender, args.password) @@ -314,6 +328,13 @@ def handle_payment_token(args: argparse.Namespace) -> None: print(result) +def handle_pool_base_price(args: argparse.Namespace) -> None: + network.connect(args.network) + contract = TerminusFacet(args.address) + result = contract.pool_base_price() + print(result) + + def handle_safe_batch_transfer_from(args: argparse.Namespace) -> None: network.connect(args.network) contract = TerminusFacet(args.address) @@ -366,6 +387,16 @@ def handle_set_payment_token(args: argparse.Namespace) -> None: print(result) +def handle_set_pool_base_price(args: argparse.Namespace) -> None: + network.connect(args.network) + contract = TerminusFacet(args.address) + transaction_config = get_transaction_config(args) + result = contract.set_pool_base_price( + new_base_price=args.new_base_price, transaction_config=transaction_config + ) + print(result) + + def handle_set_uri(args: argparse.Namespace) -> None: network.connect(args.network) contract = TerminusFacet(args.address) @@ -413,6 +444,18 @@ def handle_uri(args: argparse.Namespace) -> None: print(result) +def handle_withdraw_payments(args: argparse.Namespace) -> None: + network.connect(args.network) + contract = TerminusFacet(args.address) + transaction_config = get_transaction_config(args) + result = contract.withdraw_payments( + to_address=args.to_address, + amount=args.amount, + transaction_config=transaction_config, + ) + print(result) + + def generate_cli() -> argparse.ArgumentParser: parser = argparse.ArgumentParser(description="CLI for TerminusFacet") parser.set_defaults(func=lambda _: parser.print_help()) @@ -482,6 +525,10 @@ def generate_cli() -> argparse.ArgumentParser: add_default_arguments(payment_token_parser, False) payment_token_parser.set_defaults(func=handle_payment_token) + pool_base_price_parser = subcommands.add_parser("pool-base-price") + add_default_arguments(pool_base_price_parser, False) + pool_base_price_parser.set_defaults(func=handle_pool_base_price) + safe_batch_transfer_from_parser = subcommands.add_parser("safe-batch-transfer-from") add_default_arguments(safe_batch_transfer_from_parser, True) safe_batch_transfer_from_parser.add_argument( @@ -535,6 +582,13 @@ def generate_cli() -> argparse.ArgumentParser: ) set_payment_token_parser.set_defaults(func=handle_set_payment_token) + set_pool_base_price_parser = subcommands.add_parser("set-pool-base-price") + add_default_arguments(set_pool_base_price_parser, True) + set_pool_base_price_parser.add_argument( + "--new-base-price", required=True, help="Type: uint256", type=int + ) + set_pool_base_price_parser.set_defaults(func=handle_set_pool_base_price) + set_uri_parser = subcommands.add_parser("set-uri") add_default_arguments(set_uri_parser, True) set_uri_parser.add_argument( @@ -572,6 +626,16 @@ def generate_cli() -> argparse.ArgumentParser: uri_parser.add_argument("--pool-id", required=True, help="Type: uint256", type=int) uri_parser.set_defaults(func=handle_uri) + withdraw_payments_parser = subcommands.add_parser("withdraw-payments") + add_default_arguments(withdraw_payments_parser, True) + withdraw_payments_parser.add_argument( + "--to-address", required=True, help="Type: address" + ) + withdraw_payments_parser.add_argument( + "--amount", required=True, help="Type: uint256", type=int + ) + withdraw_payments_parser.set_defaults(func=handle_withdraw_payments) + return parser diff --git a/dao/test_core.py b/dao/test_core.py index 7f95891..0c95231 100644 --- a/dao/test_core.py +++ b/dao/test_core.py @@ -45,7 +45,7 @@ class MoonstreamTokenTestCase(MoonstreamDAOSingleContractTestCase): cls.erc20_facet = erc20_facet.address -class TerminusTestCase(MoonstreamDAOSingleContractTestCase): +class TerminusTestCase(MoonstreamTokenTestCase): @classmethod def setUpClass(cls) -> None: super().setUpClass() diff --git a/dao/test_terminus.py b/dao/test_terminus.py index 6007151..3f8d927 100644 --- a/dao/test_terminus.py +++ b/dao/test_terminus.py @@ -2,7 +2,7 @@ import unittest from brownie import accounts -from . import TerminusFacet, TerminusInitializer +from . import ERC20Facet, TerminusFacet, TerminusInitializer from .core import facet_cut from .test_core import MoonstreamDAOSingleContractTestCase, TerminusTestCase @@ -32,15 +32,85 @@ class TestDeployment(MoonstreamDAOSingleContractTestCase): class TestPoolCreation(TerminusTestCase): - def test_create_pool(self): - diamond_address = self.terminus_contracts["Diamond"] - diamond_terminus = TerminusFacet.TerminusFacet(diamond_address) + def test_create_simple_pool(self): + moonstream_diamond_address = self.contracts["Diamond"] + diamond_moonstream = ERC20Facet.ERC20Facet(moonstream_diamond_address) + + terminus_diamond_address = self.terminus_contracts["Diamond"] + diamond_terminus = TerminusFacet.TerminusFacet(terminus_diamond_address) + + diamond_terminus.set_payment_token( + moonstream_diamond_address, {"from": accounts[0]} + ) + payment_token = diamond_terminus.payment_token() + self.assertEqual(payment_token, moonstream_diamond_address) + + diamond_terminus.set_pool_base_price(1000, {"from": accounts[0]}) + pool_base_price = diamond_terminus.pool_base_price() + self.assertEqual(pool_base_price, 1000) + + diamond_moonstream.mint(accounts[1], 1000, {"from": accounts[0]}) + initial_payer_balance = diamond_moonstream.balance_of(accounts[1].address) + initial_terminus_balance = diamond_moonstream.balance_of( + terminus_diamond_address + ) + initial_controller_balance = diamond_moonstream.balance_of(accounts[0].address) + + diamond_moonstream.approve( + terminus_diamond_address, 1000, {"from": accounts[1]} + ) initial_total_pools = diamond_terminus.total_pools() - diamond_terminus.create_pool({"from": accounts[1]}) + + diamond_terminus.create_simple_pool({"from": accounts[1]}) + final_total_pools = diamond_terminus.total_pools() self.assertEqual(final_total_pools, initial_total_pools + 1) + final_payer_balance = diamond_moonstream.balance_of(accounts[1].address) + intermediate_terminus_balance = diamond_moonstream.balance_of( + terminus_diamond_address + ) + intermediate_controller_balance = diamond_moonstream.balance_of( + accounts[0].address + ) + self.assertEqual(final_payer_balance, initial_payer_balance - 1000) + self.assertEqual(intermediate_terminus_balance, initial_terminus_balance + 1000) + self.assertEqual(intermediate_controller_balance, initial_controller_balance) + + with self.assertRaises(Exception): + diamond_terminus.withdraw_payments( + accounts[1].address, 1000, {"from": accounts[1]} + ) + + with self.assertRaises(Exception): + diamond_terminus.withdraw_payments( + accounts[0].address, 1000, {"from": accounts[1]} + ) + + with self.assertRaises(Exception): + diamond_terminus.withdraw_payments( + accounts[1].address, 1000, {"from": accounts[0]} + ) + + diamond_terminus.withdraw_payments( + accounts[0].address, 1000, {"from": accounts[0]} + ) + + final_terminus_balance = diamond_moonstream.balance_of(terminus_diamond_address) + final_controller_balance = diamond_moonstream.balance_of(accounts[0].address) + self.assertEqual(final_terminus_balance, intermediate_terminus_balance - 1000) + self.assertEqual( + final_controller_balance, intermediate_controller_balance + 1000 + ) + + with self.assertRaises(Exception): + diamond_terminus.withdraw_payments( + accounts[0].address, + final_terminus_balance + 1000, + {"from": accounts[0]}, + ) + pool_controller = diamond_terminus.terminus_pool_controller(final_total_pools) self.assertEqual(pool_controller, accounts[1].address)