Skip to content

Instantly share code, notes, and snippets.

@my8bit
Last active October 15, 2021 14:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save my8bit/fb055ea9237431b3384a352a25c474cd to your computer and use it in GitHub Desktop.
Save my8bit/fb055ea9237431b3384a352a25c474cd to your computer and use it in GitHub Desktop.
security challange
from pytezos.sandbox.node import SandboxedNodeTestCase
from pytezos import ContractInterface, pytezos, MichelsonRuntimeError
from pytezos.rpc.errors import MichelsonError
import pytest
CONTRACTS = {
'token': ContractInterface.from_file('build/token.tz'),
'swap': ContractInterface.from_file('build/swap.tz')
}
# В сторадже токена подготовлен один NFT объект:
TOKEN_STORAGE = {
"ledger": {
5: "tz1S6V1YfUqt7facXpdk68JQ11mD8qUh5Yex"
},
"metadata": {
"": "68747470733a2f2f676973742e67697468756275736572636f6e74656e742e636f6d2f7a7465706c65722f37356566643933323436363964336536663836343636363537353537336666322f7261772f336332643363386634656364336432613265343064623364373863393131393066366139346433662f636f6e74726163745f6d6574612e6a736f6e"
},
"operators": {},
"token_metadata": {
5: (
5,
{
"": "68747470733a2f2f676973742e67697468756275736572636f6e74656e742e636f6d2f7a7465706c65722f32633135373665616133643765633134376665396535343938626661353264332f7261772f303765656130653836613366363234656436326662343030313834333537336139383932333133652f6e66745f6d6574612e6a736f6e"
}
),
6: (
6,
{
"": "68747470733a2f2f676973742e67697468756275736572636f6e74656e742e636f6d2f7a7465706c65722f32633135373665616133643765633134376665396535343938626661353264332f7261772f303765656130653836613366363234656436326662343030313834333537336139383932333133652f6e66745f6d6574612e6a736f6e"
}
)
}
}
class ContractInteractionsTestCase(SandboxedNodeTestCase):
def _deploy_token(self):
token = CONTRACTS['token'].using(
shell=self.get_node_url(),
key=self.manager.key)
# Привязываем выпущенный токен к публичному ключу аккаунта используемого
# для тестов:
token_storage = TOKEN_STORAGE
token_storage['ledger'].update({5: self.manager.key.public_key_hash()})
# TODO
token_storage['ledger'].update({6: self.seller.key.public_key_hash()})
opg = token.originate(initial_storage=TOKEN_STORAGE).send()
self.bake_block()
opg = self.manager.shell.blocks['head':].find_operation(opg.hash())
op_result = opg['contents'][0]['metadata']['operation_result']
address = op_result['originated_contracts'][0]
self.token = self.manager.contract(address)
def _deploy_swap(self):
swap = CONTRACTS['swap'].using(
shell=self.get_node_url(),
key=self.manager.key)
initial_storage = {
'swaps': {},
'token_address': self.token.address,
'metadata': {}
}
opg = swap.originate(initial_storage=initial_storage).send()
self.bake_block()
opg = self.manager.shell.blocks['head':].find_operation(opg.hash())
op_result = opg['contents'][0]['metadata']['operation_result']
address = op_result['originated_contracts'][0]
self.swap = self.manager.contract(address)
def setUp(self):
self.manager = self.client.using(key='bootstrap1')
self.manager.reveal()
self.seller = self.client.using(key='bootstrap2')
self.seller.reveal()
self.buyer = self.client.using(key='bootstrap3')
self.buyer.reveal()
self.hijacker = self.client.using(key='bootstrap4')
self.hijacker.reveal()
self._deploy_token()
self._deploy_swap()
def test_integration_list_accept(self):
update_operators_param = [{'add_operator': {
'owner': self.manager.key.public_key_hash(),
'operator': self.swap.address,
'token_id': 5
}}]
self.token.update_operators(update_operators_param).send()
self.bake_block()
self.swap.list({'token_id': 5, 'ask_price': 10_000_000}).send()
self.bake_block()
# Проверка что токен теперь на своп контракте:
self.assertEqual(
self.token.storage['ledger'][5](),
self.swap.address
)
# Покупка токена за 10 тезосов:
self.manager.contract(
self.swap.address).accept(5).with_amount(10_000_000).send()
self.bake_block()
# Проверка что токен вернулся обратно на аккаунт менеджера:
self.assertEqual(
self.token.storage['ledger'][5](),
self.manager.key.public_key_hash()
)
def test_integration_accept_cancel_rights(self):
update_operators_param = [
{'add_operator': {
'owner': self.manager.key.public_key_hash(),
'operator': self.swap.address,
'token_id': 5
}}
]
self.token.update_operators(update_operators_param).send()
self.bake_block()
update_operators_param_seller = [
{'add_operator': {
'owner': self.seller.key.public_key_hash(),
'operator': self.swap.address,
'token_id': 6
}}
]
self.seller.contract(self.token.address).update_operators(update_operators_param_seller).send()
self.bake_block()
self.swap.list({'token_id': 5, 'ask_price': 10_000_000}).send()
self.bake_block()
self.assertEqual(
self.token.storage['ledger'][5](),
self.swap.address
)
with self.assertRaises(MichelsonError) as err:
self.seller.contract(self.swap.address).cancel(5).send()
self.bake_block()
assert 'Listing can be canceled only by the owner' in str(err.exception)
def test_integration_accept_correct_price(self):
update_operators_param = [
{'add_operator': {
'owner': self.manager.key.public_key_hash(),
'operator': self.swap.address,
'token_id': 5
}}
]
self.token.update_operators(update_operators_param).send()
self.bake_block()
update_operators_param_seller = [
{'add_operator': {
'owner': self.seller.key.public_key_hash(),
'operator': self.swap.address,
'token_id': 6
}}
]
self.seller.contract(self.token.address).update_operators(update_operators_param_seller).send()
self.bake_block()
self.swap.list({'token_id': 5, 'ask_price': 10_000_000}).send()
self.bake_block()
with self.assertRaises(MichelsonError) as err:
self.seller.contract(self.swap.address).accept(5).with_amount(1).send();
self.bake_block()
assert 'Sent amount is not equal to asking price' in str(err.exception)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment