diff --git a/contracts/terminus/TerminusFacet.sol b/contracts/terminus/TerminusFacet.sol index dc819e8..9c1247c 100644 --- a/contracts/terminus/TerminusFacet.sol +++ b/contracts/terminus/TerminusFacet.sol @@ -49,12 +49,15 @@ contract TerminusFacet is ERC1155WithTerminusStorage { address[] memory toAddresses, uint256[] memory amounts ) public { - address operator = _msgSender(); - LibTerminus.enforcePoolIsController(id, operator); require( toAddresses.length == amounts.length, "TerminusFacet: _poolMintBatch -- toAddresses and amounts length mismatch" ); + address operator = _msgSender(); + require( + isApprovedForPool(id, operator), + "TerminusFacet: poolMintBatch -- caller is neither owner nor approved" + ); LibTerminus.TerminusStorage storage ts = LibTerminus.terminusStorage(); @@ -250,7 +253,10 @@ contract TerminusFacet is ERC1155WithTerminusStorage { uint256 amount, bytes memory data ) external { - LibTerminus.enforcePoolIsController(poolID, msg.sender); + require( + isApprovedForPool(poolID, msg.sender), + "TerminusFacet: mint -- caller is neither owner nor approved" + ); _mint(to, poolID, amount, data); } @@ -261,7 +267,10 @@ contract TerminusFacet is ERC1155WithTerminusStorage { bytes memory data ) external { for (uint256 i = 0; i < poolIDs.length; i++) { - LibTerminus.enforcePoolIsController(poolIDs[i], _msgSender()); + require( + isApprovedForPool(poolIDs[i], msg.sender), + "TerminusFacet: mintBatch -- caller is neither owner nor approved" + ); } _mintBatch(to, poolIDs, amounts, data); } diff --git a/dao/test_terminus.py b/dao/test_terminus.py index 62e3e67..3a67125 100644 --- a/dao/test_terminus.py +++ b/dao/test_terminus.py @@ -273,6 +273,64 @@ def test_mint_batch(self): supply = self.diamond_terminus.terminus_pool_supply(pool_id) self.assertEqual(supply, 1) + def test_mint_batch_with_approval(self): + pool_id = self.diamond_terminus.total_pools() + + self.assertFalse( + self.diamond_terminus.is_approved_for_pool(pool_id, accounts[3]) + ) + self.assertFalse( + self.diamond_terminus.is_approved_for_pool(pool_id - 1, accounts[3]) + ) + balances_before = [ + self.diamond_terminus.balance_of(accounts[2].address, pool_id), + self.diamond_terminus.balance_of(accounts[2].address, pool_id - 1), + ] + supply_before = [ + self.diamond_terminus.terminus_pool_supply(pool_id), + self.diamond_terminus.terminus_pool_supply(pool_id - 1), + ] + self.diamond_terminus.approve_for_pool( + pool_id, accounts[3], {"from": accounts[1]} + ) + with self.assertRaises(Exception): + self.diamond_terminus.mint_batch( + accounts[2].address, + pool_i_ds=[pool_id, pool_id - 1], + amounts=[1, 1], + data=b"", + transaction_config={"from": accounts[3]}, + ) + + self.diamond_terminus.approve_for_pool( + pool_id - 1, accounts[3], {"from": accounts[1]} + ) + + self.diamond_terminus.mint_batch( + accounts[2].address, + pool_i_ds=[pool_id, pool_id - 1], + amounts=[1, 1], + data=b"", + transaction_config={"from": accounts[3]}, + ) + + self.assertEqual( + self.diamond_terminus.balance_of(accounts[2].address, pool_id), + balances_before[0] + 1, + ) + self.assertEqual( + self.diamond_terminus.balance_of(accounts[2].address, pool_id - 1), + balances_before[1] + 1, + ) + + self.assertEqual( + self.diamond_terminus.terminus_pool_supply(pool_id), supply_before[0] + 1 + ) + self.assertEqual( + self.diamond_terminus.terminus_pool_supply(pool_id - 1), + supply_before[1] + 1, + ) + def test_mint_batch_fails_if_it_exceeds_capacity(self): pool_id = self.diamond_terminus.total_pools() with self.assertRaises(Exception): @@ -350,6 +408,64 @@ def test_pool_mint_batch_as_unauthorized_third_party(self): final_balance = self.diamond_terminus.balance_of(account.address, pool_id) self.assertEqual(final_balance, initial_balances[i]) + def test_pool_mint_with_pool_approval(self): + self.diamond_terminus.create_pool_v1(10, False, False, {"from": accounts[1]}) + pool_id = self.diamond_terminus.total_pools() + + self.assertFalse( + self.diamond_terminus.is_approved_for_pool(pool_id, accounts[2].address) + ) + with self.assertRaises(Exception): + self.diamond_terminus.mint( + accounts[2].address, pool_id, 1, b"", {"from": accounts[2]} + ) + + self.diamond_terminus.approve_for_pool( + pool_id, accounts[2].address, {"from": accounts[1]} + ) + supply_0 = self.diamond_terminus.terminus_pool_supply(pool_id) + balance_0 = self.diamond_terminus.balance_of(accounts[2].address, pool_id) + self.diamond_terminus.mint( + accounts[2].address, pool_id, 1, b"", {"from": accounts[1]} + ) + balance_1 = self.diamond_terminus.balance_of(accounts[2].address, pool_id) + supply_1 = self.diamond_terminus.terminus_pool_supply(pool_id) + + self.assertEqual(balance_1, balance_0 + 1) + self.assertEqual(supply_0 + 1, supply_1) + + def test_pool_mint_batch_with_approval(self): + pool_id = self.diamond_terminus.total_pools() + target_accounts = [account.address for account in accounts[:5]] + target_amounts = [1 for _ in accounts[:5]] + num_accounts = len(accounts[:5]) + initial_pool_supply = self.diamond_terminus.terminus_pool_supply(pool_id) + initial_balances: List[int] = [] + for account in accounts[:5]: + initial_balances.append( + self.diamond_terminus.balance_of(account.address, pool_id) + ) + + self.assertFalse( + self.diamond_terminus.is_approved_for_pool(pool_id, accounts[2].address) + ) + with self.assertRaises(Exception): + self.diamond_terminus.pool_mint_batch( + pool_id, target_accounts, target_amounts, {"from": accounts[2]} + ) + self.diamond_terminus.approve_for_pool( + pool_id, accounts[2].address, {"from": accounts[1]} + ) + self.diamond_terminus.pool_mint_batch( + pool_id, target_accounts, target_amounts, {"from": accounts[2]} + ) + + final_pool_supply = self.diamond_terminus.terminus_pool_supply(pool_id) + self.assertEqual(final_pool_supply, initial_pool_supply + num_accounts) + for i, account in enumerate(accounts[:5]): + final_balance = self.diamond_terminus.balance_of(account.address, pool_id) + self.assertEqual(final_balance, initial_balances[i] + 1) + def test_transfer(self): pool_id = self.diamond_terminus.total_pools() self.diamond_terminus.mint(accounts[2], pool_id, 1, b"", {"from": accounts[1]}) diff --git a/setup.py b/setup.py index f02f7db..0f2de67 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ setup( name="moonstream-dao", - version="0.0.6", + version="0.0.7", packages=find_packages(), install_requires=["eth-brownie", "tqdm"], extras_require={