Merge branch 'main' into faucet

pull/16/head
yhtiyar 2021-12-23 15:40:54 +03:00
commit 498fbaa7c7
10 zmienionych plików z 644 dodań i 21 usunięć

Wyświetl plik

@ -0,0 +1,111 @@
# Deploy 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 deploy the contract.
## Deployed addresses
You will modify this section as you go through the checklist
### Diamond addresses
```json
```
### `TerminusInitializer` address
```
export TERMINUS_INITIALIZER_ADDRESS=""
```
### `TerminusFacet` address
```
export TERMINUS_FACET_ADDRESS=""
```
## Environment variables
- [ ] `export DAO_NETWORK=<desired brownie network>`
- [ ] `export DAO_OWNER=<path to keystore file for owner account>`
- [ ] `export DAO_OWNER_ADDRESS=$(jq -r .address $DAO_OWNER)`
- [ ] `export GAS_PRICE="<N> gwei"`
- [ ] `export CONFIRMATIONS=<M>`
- [ ] `export TERMINUS_ADDRESSES=<path to JSON file in which to store diamond addresses>`
## Deploy diamond proxy
- [ ] Deploy diamond with all core facets
```bash
dao core gogogo \
--network $DAO_NETWORK \
--sender $DAO_OWNER \
--gas-price "$GAS_PRICE" \
--confirmations $CONFIRMATIONS \
--owner $DAO_OWNER_ADDRESS \
--outfile $TERMINUS_ADDRESSES
```
- [ ] Store JSON output under `Deployed addresses / Diamond addresses` above.
- [ ] Export diamond proxy address: `export TERMINUS_DIAMOND="$(jq -r .Diamond $TERMINUS_ADDRESSES)"`
## Deploy `TerminusInitializer`
- [ ] Deploy `TerminusInitializer` contract
```bash
dao moonstream-initializer deploy \
--network $DAO_NETWORK \
--sender $DAO_OWNER \
--gas-price "$GAS_PRICE" \
--confirmations $CONFIRMATIONS
```
- [ ] Export address of deployed contract as `export TERMINUS_INITIALIZER_ADDRESS=<address>`
- [ ] Store address of deployed contract under `Deployed addresses / TerminusInitializer address` above
## Deploy `TerminusFacet`
- [ ] Deploy `TerminusFacet` contract
```bash
dao terminus deploy \
--network $DAO_NETWORK \
--sender $DAO_OWNER \
--gas-price "$GAS_PRICE" \
--confirmations $CONFIRMATIONS
```
- [ ] Export address of deployed contract as `export TERMINUS_FACET_ADDRESS=<address>`
- [ ] Store address of deployed contract under `Deployed addresses / TerminusFacet address` above
- [ ] 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 \
--initializer-address $TERMINUS_INITIALIZER_ADDRESS
```
- [ ] Check the number of pools on the Terminus contract: `dao terminus total-pools --network $DAO_NETWORK --address $TERMINUS_DIAMOND`
- [ ] Number of pools is `0`
- [ ] Check the Terminus controller: `dao terminus terminus-controller --network $DAO_NETWORK --address $TERMINUS_DIAMOND`
- [ ] Controller should be the same as `$DAO_OWNER_ADDRESS`

Wyświetl plik

@ -0,0 +1,49 @@
# Set up the Terminus contract
This checklist describes how to activate the Terminus contract so that projects can start using it for
decentralized authorization.
## Environment variables
- [ ] `export DAO_NETWORK=<desired brownie network>`
- [ ] `export DAO_OWNER=<path to keystore file for owner account>`
- [ ] `export DAO_OWNER_ADDRESS=$(jq -r .address $DAO_OWNER)`
- [ ] `export GAS_PRICE="<N> gwei"`
- [ ] `export CONFIRMATIONS=<M>`
- [ ] `export MOONSTREAM_DIAMOND=<address of Moonstream token diamond proxy>`
- [ ] `export TERMINUS_DIAMOND=<address of Terminus diamond proxy>`
- [ ] `export TERMINUS_POOL_BASE_PRICE=<base price for creation of Terminus pools>`
## Set up Terminus so that people can create pools
- [ ] Set pool base price:
```bash
dao terminus set-pool-base-price \
--network $DAO_NETWORK \
--address $TERMINUS_DIAMOND \
--sender $DAO_OWNER \
--gas-price "$GAS_PRICE" \
--confirmations $CONFIRMATIONS \
--new-base-price $TERMINUS_POOL_BASE_PRICE
```
- [ ] Check pool base price: `dao terminus pool-base-price --network $DAO_NETWORK --address $TERMINUS_DIAMOND`
- [ ] Pool base price should be same as `$TERMINUS_POOL_BASE_PRICE`
- [ ] Set up payment token:
```bash
dao terminus set-payment-token \
--network $DAO_NETWORK \
--address $TERMINUS_DIAMOND \
--sender $DAO_OWNER \
--gas-price "$GAS_PRICE" \
--confirmations $CONFIRMATIONS \
--new-payment-token $MOONSTREAM_DIAMOND
```
- [ ] Check payment token: `dao terminus payment-token --network $DAO_NETWORK --address $TERMINUS_DIAMOND`
- [ ] Payment token should be same as `$MOONSTREAM_DIAMOND`

Wyświetl plik

@ -0,0 +1,121 @@
# Deploy 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 deploy the contract.
## Deployed addresses
You will modify this section as you go through the checklist
### Diamond addresses
```json
{
"DiamondCutFacet": "0xda30781C3c8d4c81804E6Bf5c02D5E7898180dd7",
"Diamond": "0x040Cf7Ee9752936d8d280062a447eB53808EBc08",
"DiamondLoupeFacet": "0xEC5d886Bc5A7Fc31C76A5aB144c65C75AFa73Aea",
"OwnershipFacet": "0x2725E9FE8f5C97400d324C529e9ACBAd213E68b9",
"attached": [
"DiamondLoupeFacet",
"OwnershipFacet"
]
}
```
### `TerminusInitializer` address
```
export TERMINUS_INITIALIZER_ADDRESS="0xba71CB745C499D4A4f42Fd7aA40044b3b27Da6D4"
```
### `TerminusFacet` address
```
export TERMINUS_FACET_ADDRESS="0x9784e26967779e62450Eb204077EF70B4c7A3612"
```
## 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_ADDRESSES=.secrets/terminus-mumbai-diamond.json`
## Deploy diamond proxy
- [x] Deploy diamond with all core facets
```bash
dao core gogogo \
--network $DAO_NETWORK \
--sender $DAO_OWNER \
--gas-price "$GAS_PRICE" \
--confirmations $CONFIRMATIONS \
--owner $DAO_OWNER_ADDRESS \
--outfile $TERMINUS_ADDRESSES
```
- [x] Store JSON output under `Deployed addresses / Diamond addresses` above.
- [x] Export diamond proxy address: `export TERMINUS_DIAMOND="$(jq -r .Diamond $TERMINUS_ADDRESSES)"`
## Deploy `TerminusInitializer`
- [x] Deploy `TerminusInitializer` contract
```bash
dao terminus-initializer deploy \
--network $DAO_NETWORK \
--sender $DAO_OWNER \
--gas-price "$GAS_PRICE" \
--confirmations $CONFIRMATIONS
```
- [x] Export address of deployed contract as `export TERMINUS_INITIALIZER_ADDRESS=0xba71CB745C499D4A4f42Fd7aA40044b3b27Da6D4`
- [x] Store address of deployed contract under `Deployed addresses / TerminusInitializer address` above
## 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=0x9784e26967779e62450Eb204077EF70B4c7A3612`
- [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 \
--initializer-address $TERMINUS_INITIALIZER_ADDRESS
```
- [x] Check the number of pools on the Terminus contract: `dao terminus total-pools --network $DAO_NETWORK --address $TERMINUS_DIAMOND`
- [x] Number of pools is `0`
- [x] Check the Terminus controller: `dao terminus terminus-controller --network $DAO_NETWORK --address $TERMINUS_DIAMOND`
- [x] Controller should be the same as `$DAO_OWNER_ADDRESS`

Wyświetl plik

@ -0,0 +1,49 @@
# Set up the Terminus contract
This checklist describes how to activate the Terminus contract so that projects can start using it for
decentralized authorization.
## 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 MOONSTREAM_DIAMOND=$(jq -r .Diamond .secrets/moonstream-mumbai-diamond.json)`
- [x] `export TERMINUS_DIAMOND=$(jq -r .Diamond .secrets/terminus-mumbai-diamond.json)`
- [ ] `export TERMINUS_POOL_BASE_PRICE=1000000000000000000`
## Set up Terminus so that people can create pools
- [x] Set pool base price:
```bash
dao terminus set-pool-base-price \
--network $DAO_NETWORK \
--address $TERMINUS_DIAMOND \
--sender $DAO_OWNER \
--gas-price "$GAS_PRICE" \
--confirmations $CONFIRMATIONS \
--new-base-price $TERMINUS_POOL_BASE_PRICE
```
- [x] Check pool base price: `dao terminus pool-base-price --network $DAO_NETWORK --address $TERMINUS_DIAMOND`
- [x] Pool base price should be same as `$TERMINUS_POOL_BASE_PRICE`
- [x] Set up payment token:
```bash
dao terminus set-payment-token \
--network $DAO_NETWORK \
--address $TERMINUS_DIAMOND \
--sender $DAO_OWNER \
--gas-price "$GAS_PRICE" \
--confirmations $CONFIRMATIONS \
--new-payment-token $MOONSTREAM_DIAMOND
```
- [x] Check payment token: `dao terminus payment-token --network $DAO_NETWORK --address $TERMINUS_DIAMOND`
- [x] Payment token should be same as `$MOONSTREAM_DIAMOND`

Wyświetl plik

@ -140,11 +140,12 @@ contract ERC1155WithTerminusStorage is
view
returns (bool)
{
LibTerminus.TerminusStorage storage ts = LibTerminus.terminusStorage();
if (operator == ts.poolController[poolID]) {
return true;
}
return false;
return LibTerminus._isApprovedForPool(poolID, operator);
}
function approveForPool(uint256 poolID, address operator) external {
LibTerminus.enforcePoolIsController(poolID, _msgSender());
LibTerminus._approveForPool(poolID, operator);
}
/**
@ -428,11 +429,6 @@ contract ERC1155WithTerminusStorage is
address operator = _msgSender();
require(
operator == from || isApprovedForPool(id, operator),
"ERC1155WithTerminusStorage: _burn -- caller is neither owner nor approved"
);
_beforeTokenTransfer(
operator,
from,
@ -478,22 +474,13 @@ contract ERC1155WithTerminusStorage is
address operator = _msgSender();
bool approvedForPools = true;
LibTerminus.TerminusStorage storage ts = LibTerminus.terminusStorage();
for (uint256 i = 0; i < ids.length; i++) {
require(
ts.poolBurnable[ids[i]],
"ERC1155WithTerminusStorage: _burnBatch -- pool is not burnable"
);
if (!isApprovedForPool(ids[i], operator)) {
approvedForPools = false;
}
}
require(
from == _msgSender() || approvedForPools,
"ERC1155WithTerminusStorage: _burnBatch -- caller is neither owner nor approved"
);
_beforeTokenTransfer(operator, from, address(0), ids, amounts, "");

Wyświetl plik

@ -34,6 +34,7 @@ library LibTerminus {
mapping(uint256 => bool) poolNotTransferable;
mapping(uint256 => bool) poolBurnable;
mapping(address => mapping(address => bool)) globalOperatorApprovals;
mapping(uint256 => mapping(address => bool)) globalPoolOperatorApprovals;
}
function terminusStorage()
@ -101,4 +102,23 @@ library LibTerminus {
"LibTerminus: Must be pool controller"
);
}
function _isApprovedForPool(uint256 poolID, address operator)
internal
view
returns (bool)
{
LibTerminus.TerminusStorage storage ts = LibTerminus.terminusStorage();
if (operator == ts.poolController[poolID]) {
return true;
} else if (ts.globalPoolOperatorApprovals[poolID][operator]) {
return true;
}
return false;
}
function _approveForPool(uint256 poolID, address operator) internal {
LibTerminus.TerminusStorage storage ts = LibTerminus.terminusStorage();
ts.globalPoolOperatorApprovals[poolID][operator] = true;
}
}

Wyświetl plik

@ -28,6 +28,52 @@ import "../diamond/libraries/LibDiamond.sol";
contract TerminusFacet is ERC1155WithTerminusStorage {
constructor() {}
event PoolMintBatch(
uint256 indexed id,
address indexed operator,
address from,
address[] toAddresses,
uint256[] amounts
);
function poolMintBatch(
uint256 id,
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"
);
LibTerminus.TerminusStorage storage ts = LibTerminus.terminusStorage();
uint256 i = 0;
uint256 totalAmount = 0;
for (i = 0; i < toAddresses.length; i++) {
address to = toAddresses[i];
uint256 amount = amounts[i];
require(
to != address(0),
"TerminusFacet: _poolMintBatch -- cannot mint to zero address"
);
totalAmount += amount;
ts.poolBalances[id][to] += amount;
emit TransferSingle(operator, address(0), to, id, amount);
}
require(
ts.poolSupply[id] + totalAmount <= ts.poolCapacity[id],
"TerminusFacet: _poolMintBatch -- Minted tokens would exceed pool capacity"
);
ts.poolSupply[id] += totalAmount;
emit PoolMintBatch(id, operator, address(0), toAddresses, amounts);
}
function terminusController() external view returns (address) {
return LibTerminus.terminusStorage().controller;
}
@ -180,6 +226,11 @@ contract TerminusFacet is ERC1155WithTerminusStorage {
uint256 poolID,
uint256 amount
) external {
address operator = _msgSender();
require(
operator == from || isApprovedForPool(poolID, operator),
"TerminusFacet: burn -- caller is neither owner nor approved"
);
_burn(from, poolID, amount);
}
}

Wyświetl plik

@ -20,7 +20,7 @@ contract TerminusInitializer {
ds.supportedInterfaces[type(IERC1155).interfaceId] = true;
ds.supportedInterfaces[type(IERC1155MetadataURI).interfaceId] = true;
LibTerminus.TerminusStorage storage es = LibTerminus.terminusStorage();
es.controller = msg.sender;
LibTerminus.TerminusStorage storage ts = LibTerminus.terminusStorage();
ts.controller = msg.sender;
}
}

Wyświetl plik

@ -90,6 +90,12 @@ class TerminusFacet:
if self.contract is None:
raise Exception("contract has not been instantiated")
def approve_for_pool(
self, pool_id: int, operator: ChecksumAddress, transaction_config
) -> Any:
self.assert_contract_is_instantiated()
return self.contract.approveForPool(pool_id, operator, transaction_config)
def balance_of(self, account: ChecksumAddress, id: int) -> Any:
self.assert_contract_is_instantiated()
return self.contract.balanceOf.call(account, id)
@ -156,6 +162,14 @@ class TerminusFacet:
self.assert_contract_is_instantiated()
return self.contract.poolBasePrice.call()
def pool_mint_batch(
self, id: int, to_addresses: List, amounts: List, transaction_config
) -> Any:
self.assert_contract_is_instantiated()
return self.contract.poolMintBatch(
id, to_addresses, amounts, transaction_config
)
def safe_batch_transfer_from(
self,
from_: ChecksumAddress,
@ -290,6 +304,18 @@ def handle_deploy(args: argparse.Namespace) -> None:
print(result)
def handle_approve_for_pool(args: argparse.Namespace) -> None:
network.connect(args.network)
contract = TerminusFacet(args.address)
transaction_config = get_transaction_config(args)
result = contract.approve_for_pool(
pool_id=args.pool_id,
operator=args.operator,
transaction_config=transaction_config,
)
print(result)
def handle_balance_of(args: argparse.Namespace) -> None:
network.connect(args.network)
contract = TerminusFacet(args.address)
@ -396,6 +422,19 @@ def handle_pool_base_price(args: argparse.Namespace) -> None:
print(result)
def handle_pool_mint_batch(args: argparse.Namespace) -> None:
network.connect(args.network)
contract = TerminusFacet(args.address)
transaction_config = get_transaction_config(args)
result = contract.pool_mint_batch(
id=args.id,
to_addresses=args.to_addresses,
amounts=args.amounts,
transaction_config=transaction_config,
)
print(result)
def handle_safe_batch_transfer_from(args: argparse.Namespace) -> None:
network.connect(args.network)
contract = TerminusFacet(args.address)
@ -540,6 +579,16 @@ def generate_cli() -> argparse.ArgumentParser:
add_default_arguments(deploy_parser, True)
deploy_parser.set_defaults(func=handle_deploy)
approve_for_pool_parser = subcommands.add_parser("approve-for-pool")
add_default_arguments(approve_for_pool_parser, True)
approve_for_pool_parser.add_argument(
"--pool-id", required=True, help="Type: uint256", type=int
)
approve_for_pool_parser.add_argument(
"--operator", required=True, help="Type: address"
)
approve_for_pool_parser.set_defaults(func=handle_approve_for_pool)
balance_of_parser = subcommands.add_parser("balance-of")
add_default_arguments(balance_of_parser, False)
balance_of_parser.add_argument("--account", required=True, help="Type: address")
@ -640,6 +689,19 @@ def generate_cli() -> argparse.ArgumentParser:
add_default_arguments(pool_base_price_parser, False)
pool_base_price_parser.set_defaults(func=handle_pool_base_price)
pool_mint_batch_parser = subcommands.add_parser("pool-mint-batch")
add_default_arguments(pool_mint_batch_parser, True)
pool_mint_batch_parser.add_argument(
"--id", required=True, help="Type: uint256", type=int
)
pool_mint_batch_parser.add_argument(
"--to-addresses", required=True, help="Type: address[]", nargs="+"
)
pool_mint_batch_parser.add_argument(
"--amounts", required=True, help="Type: uint256[]", nargs="+"
)
pool_mint_batch_parser.set_defaults(func=handle_pool_mint_batch)
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(

Wyświetl plik

@ -1,3 +1,4 @@
from typing import List
import unittest
from brownie import accounts
@ -196,6 +197,66 @@ class TestPoolOperations(TerminusTestCase):
supply = self.diamond_terminus.terminus_pool_supply(pool_id)
self.assertEqual(supply, 0)
def test_pool_mint_batch(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.diamond_terminus.pool_mint_batch(
pool_id, target_accounts, target_amounts, {"from": accounts[1]}
)
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_pool_mint_batch_as_contract_controller_not_pool_controller(self):
pool_id = self.diamond_terminus.total_pools()
target_accounts = [account.address for account in accounts[:5]]
target_amounts = [1 for _ in 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)
)
with self.assertRaises(Exception):
self.diamond_terminus.pool_mint_batch(
pool_id, target_accounts, target_amounts, {"from": accounts[0]}
)
final_pool_supply = self.diamond_terminus.terminus_pool_supply(pool_id)
self.assertEqual(final_pool_supply, initial_pool_supply)
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])
def test_pool_mint_batch_as_unauthorized_third_party(self):
pool_id = self.diamond_terminus.total_pools()
target_accounts = [account.address for account in accounts[:5]]
target_amounts = [1 for _ in 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)
)
with self.assertRaises(Exception):
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)
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])
def test_transfer(self):
pool_id = self.diamond_terminus.total_pools()
self.diamond_terminus.mint(accounts[2], pool_id, 1, b"", {"from": accounts[1]})
@ -287,6 +348,39 @@ class TestPoolOperations(TerminusTestCase):
self.assertEqual(final_sender_balance, initial_sender_balance)
self.assertEqual(final_receiver_balance, initial_receiver_balance)
def test_transfer_as_authorized_recipient(self):
pool_id = self.diamond_terminus.total_pools()
self.diamond_terminus.mint(accounts[2], pool_id, 1, b"", {"from": accounts[1]})
initial_sender_balance = self.diamond_terminus.balance_of(
accounts[2].address, pool_id
)
initial_receiver_balance = self.diamond_terminus.balance_of(
accounts[3].address, pool_id
)
self.diamond_terminus.approve_for_pool(
pool_id, accounts[3].address, {"from": accounts[1]}
)
self.diamond_terminus.safe_transfer_from(
accounts[2].address,
accounts[3].address,
pool_id,
1,
b"",
{"from": accounts[3]},
)
final_sender_balance = self.diamond_terminus.balance_of(
accounts[2].address, pool_id
)
final_receiver_balance = self.diamond_terminus.balance_of(
accounts[3].address, pool_id
)
self.assertEqual(final_sender_balance, initial_sender_balance - 1)
self.assertEqual(final_receiver_balance, initial_receiver_balance + 1)
def test_transfer_as_unauthorized_unrelated_party(self):
pool_id = self.diamond_terminus.total_pools()
self.diamond_terminus.mint(accounts[2], pool_id, 1, b"", {"from": accounts[1]})
@ -318,6 +412,39 @@ class TestPoolOperations(TerminusTestCase):
self.assertEqual(final_sender_balance, initial_sender_balance)
self.assertEqual(final_receiver_balance, initial_receiver_balance)
def test_transfer_as_authorized_unrelated_party(self):
pool_id = self.diamond_terminus.total_pools()
self.diamond_terminus.mint(accounts[2], pool_id, 1, b"", {"from": accounts[1]})
initial_sender_balance = self.diamond_terminus.balance_of(
accounts[2].address, pool_id
)
initial_receiver_balance = self.diamond_terminus.balance_of(
accounts[3].address, pool_id
)
self.diamond_terminus.approve_for_pool(
pool_id, accounts[4].address, {"from": accounts[1]}
)
self.diamond_terminus.safe_transfer_from(
accounts[2].address,
accounts[3].address,
pool_id,
1,
b"",
{"from": accounts[4]},
)
final_sender_balance = self.diamond_terminus.balance_of(
accounts[2].address, pool_id
)
final_receiver_balance = self.diamond_terminus.balance_of(
accounts[3].address, pool_id
)
self.assertEqual(final_sender_balance, initial_sender_balance - 1)
self.assertEqual(final_receiver_balance, initial_receiver_balance + 1)
def test_burn_fails_as_token_owner(self):
pool_id = self.diamond_terminus.total_pools()
self.diamond_terminus.mint(accounts[2], pool_id, 1, b"", {"from": accounts[1]})
@ -378,6 +505,29 @@ class TestPoolOperations(TerminusTestCase):
self.assertEqual(final_pool_supply, initial_pool_supply)
self.assertEqual(final_owner_balance, initial_owner_balance)
def test_burn_fails_as_authorized_third_party(self):
pool_id = self.diamond_terminus.total_pools()
self.diamond_terminus.mint(accounts[2], pool_id, 1, b"", {"from": accounts[1]})
initial_pool_supply = self.diamond_terminus.terminus_pool_supply(pool_id)
initial_owner_balance = self.diamond_terminus.balance_of(
accounts[2].address, pool_id
)
self.diamond_terminus.approve_for_pool(
pool_id, accounts[3].address, {"from": accounts[1]}
)
with self.assertRaises(Exception):
self.diamond_terminus.burn(
accounts[2].address, pool_id, 1, {"from": accounts[3]}
)
final_pool_supply = self.diamond_terminus.terminus_pool_supply(pool_id)
final_owner_balance = self.diamond_terminus.balance_of(
accounts[2].address, pool_id
)
self.assertEqual(final_pool_supply, initial_pool_supply)
self.assertEqual(final_owner_balance, initial_owner_balance)
class TestCreatePoolV1(TestPoolOperations):
def setUp(self):
@ -455,6 +605,29 @@ class TestCreatePoolV1(TestPoolOperations):
self.assertEqual(final_pool_supply, initial_pool_supply - 1)
self.assertEqual(final_owner_balance, initial_owner_balance - 1)
def test_burnable_pool_burn_as_authorized_third_party(self):
self.diamond_terminus.create_pool_v1(10, True, True, {"from": accounts[1]})
pool_id = self.diamond_terminus.total_pools()
self.diamond_terminus.mint(accounts[2], pool_id, 1, b"", {"from": accounts[1]})
initial_pool_supply = self.diamond_terminus.terminus_pool_supply(pool_id)
initial_owner_balance = self.diamond_terminus.balance_of(
accounts[2].address, pool_id
)
self.diamond_terminus.approve_for_pool(
pool_id, accounts[3].address, {"from": accounts[1]}
)
self.diamond_terminus.burn(
accounts[2].address, pool_id, 1, {"from": accounts[3]}
)
final_pool_supply = self.diamond_terminus.terminus_pool_supply(pool_id)
final_owner_balance = self.diamond_terminus.balance_of(
accounts[2].address, pool_id
)
self.assertEqual(final_pool_supply, initial_pool_supply - 1)
self.assertEqual(final_owner_balance, initial_owner_balance - 1)
def test_burnable_pool_burn_as_unauthorized_third_party(self):
self.diamond_terminus.create_pool_v1(10, True, True, {"from": accounts[1]})
pool_id = self.diamond_terminus.total_pools()