diff --git a/contracts/CFA12.py b/contracts/CFA12.py index fddbb0c8..e847345a 100644 --- a/contracts/CFA12.py +++ b/contracts/CFA12.py @@ -8,12 +8,14 @@ class CFA12(CToken.CToken): - def __init__(self, comptroller_, interestRateModel_, initialExchangeRateMantissa_, administrator_, fa1_2_TokenAddress_, **extra_storage): + def __init__(self, comptroller_, interestRateModel_, initialExchangeRateMantissa_, administrator_, metadata_, token_metadata_, fa1_2_TokenAddress_, **extra_storage): CToken.CToken.__init__(self, comptroller_, interestRateModel_, initialExchangeRateMantissa_, administrator_, + metadata_, + token_metadata_, fa1_2_TokenAddress=fa1_2_TokenAddress_, currentCash=sp.nat(0), **extra_storage) diff --git a/contracts/CFA2.py b/contracts/CFA2.py index cb1182bd..0f5644bf 100644 --- a/contracts/CFA2.py +++ b/contracts/CFA2.py @@ -27,12 +27,14 @@ class CFA2(CToken.CToken): - def __init__(self, comptroller_, interestRateModel_, initialExchangeRateMantissa_, administrator_, fa2_TokenAddress_, tokenId_, **extra_storage): + def __init__(self, comptroller_, interestRateModel_, initialExchangeRateMantissa_, administrator_, metadata_, token_metadata_, fa2_TokenAddress_, tokenId_, **extra_storage): CToken.CToken.__init__(self, comptroller_, interestRateModel_, initialExchangeRateMantissa_, administrator_, + metadata_, + token_metadata_, fa2_TokenAddress=fa2_TokenAddress_, tokenId=tokenId_, currentCash=sp.nat(0), diff --git a/contracts/CToken.py b/contracts/CToken.py index 43d91e24..1d0ba2fa 100644 --- a/contracts/CToken.py +++ b/contracts/CToken.py @@ -18,15 +18,17 @@ class CToken(CTI.CTokenInterface, Exponential.Exponential, SweepTokens.SweepTokens, OP.OperationProtector): - def __init__(self, comptroller_, interestRateModel_, initialExchangeRateMantissa_, administrator_, **extra_storage): + def __init__(self, comptroller_, interestRateModel_, initialExchangeRateMantissa_, administrator_, metadata_, token_metadata_, **extra_storage): Exponential.Exponential.__init__( self, - balances=sp.big_map(tkey=sp.TAddress, tvalue=sp.TRecord( + ledger=sp.big_map(tkey=sp.TAddress, tvalue=sp.TRecord( + # Official record of token ledger for each account + balance=sp.TNat, # Approved token transfer amounts on behalf of others - approvals=sp.TMap(sp.TAddress, sp.TNat), - # Mapping of account addresses to outstanding borrow balances - accountBorrows=CTI.TBorrowSnapshot, - balance=sp.TNat)), # Official record of token balances for each account + approvals=sp.TMap(sp.TAddress, sp.TNat) + )), + # Mapping of account addresses to outstanding borrow ledger + borrows=sp.big_map(tkey=sp.TAddress, tvalue=CTI.TBorrowSnapshot), totalSupply=sp.nat(0), # Total number of tokens in circulation # Maximum borrow rate that can ever be applied (.0000008% / block) borrowRateMaxMantissa=sp.nat(int(800000000000)), @@ -54,6 +56,17 @@ def __init__(self, comptroller_, interestRateModel_, initialExchangeRateMantissa # Current per-block supply interest rate supplyRatePerBlock=sp.nat(0), administrator=administrator_, # Administrator`s address for this contract + # Metadata of a contract + metadata=metadata_, + # Metadata of a token + token_metadata=sp.big_map( + l={ + 0: sp.record(token_id=0, token_info=token_metadata_) + }, + tkey=sp.TNat, + tvalue=sp.TRecord(token_id=sp.TNat, + token_info=sp.TMap(sp.TString, sp.TBytes)) + ), pendingAdministrator=sp.none, # Pending administrator`s address for this contract # Set of currently active operations to protect execution flow activeOperations=sp.set(t=sp.TNat), @@ -83,7 +96,7 @@ def mintInternal(self, params): mintTokens = self.getMintTokens(params.mintAmount) sp.verify(mintTokens > 0, EC.CT_MINT_AMOUNT_IS_INVALID) self.data.totalSupply += mintTokens - self.data.balances[params.minter].balance += mintTokens + self.data.ledger[params.minter].balance += mintTokens def verifyMintAllowed(self, minter_, mintAmount_): self.addAddressIfNecessary(minter_) @@ -155,8 +168,8 @@ def redeemInternal(self, params): self.verifyAccruedInterestRelevance() self.data.totalSupply = sp.as_nat( self.data.totalSupply - redeemTokens, "Insufficient supply") - self.data.balances[params.redeemer].balance = sp.as_nat( - self.data.balances[params.redeemer].balance - redeemTokens, "Insufficient balance") + self.data.ledger[params.redeemer].balance = sp.as_nat( + self.data.ledger[params.redeemer].balance - redeemTokens, "Insufficient balance") self.doTransferOut(params.redeemer, redeemAmount) def verifyRedeemAllowed(self, redeemer_, redeemAmount_): @@ -194,8 +207,8 @@ def borrowInternal(self, params): self.doTransferOut(params.borrower, params.borrowAmount) accountBorrows = self.getBorrowBalance( params.borrower) + params.borrowAmount - self.data.balances[params.borrower].accountBorrows.principal = accountBorrows - self.data.balances[params.borrower].accountBorrows.interestIndex = self.data.borrowIndex + self.data.borrows[params.borrower].principal = accountBorrows + self.data.borrows[params.borrower].interestIndex = self.data.borrowIndex self.data.totalBorrows += params.borrowAmount def verifyBorrowAllowed(self, borrower_, borrowAmount_): @@ -247,12 +260,12 @@ def repayBorrowInternal(self, params): accountBorrows = self.getBorrowBalance(params.borrower) repayAmount = sp.min(accountBorrows, params.repayAmount) self.doTransferIn(params.payer, repayAmount) - self.data.balances[params.borrower].accountBorrows.principal = self.sub_nat_nat( + self.data.borrows[params.borrower].principal = self.sub_nat_nat( accountBorrows, repayAmount) - self.data.balances[params.borrower].accountBorrows.interestIndex = self.data.borrowIndex + self.data.borrows[params.borrower].interestIndex = self.data.borrowIndex self.data.totalBorrows = self.sub_nat_nat( self.data.totalBorrows, repayAmount) - sp.if self.data.balances[params.borrower].accountBorrows.principal == 0: + sp.if self.data.borrows[params.borrower].principal == 0: c = sp.contract(sp.TAddress, self.data.comptroller, entry_point="removeFromLoans").open_some() sp.transfer(params.borrower, sp.mutez(0), c) @@ -291,8 +304,8 @@ def seizeInternal(self, seizerToken, liquidator, borrower, seizeTokens): self.verifyAccruedInterestRelevance() - borrowerBalance = self.data.balances[borrower].balance - liquidatorBalance = self.data.balances[liquidator].balance + borrowerBalance = self.data.ledger[borrower].balance + liquidatorBalance = self.data.ledger[liquidator].balance borrowerTokensNew = self.sub_nat_nat(borrowerBalance, seizeTokens) @@ -318,8 +331,8 @@ def seizeInternal(self, seizerToken, liquidator, borrower, seizeTokens): self.data.totalReserves = totalReservesNew self.data.totalSupply = totalSupplyNew - self.data.balances[borrower].balance = borrowerTokensNew - self.data.balances[liquidator].balance = liquidatorTokensNew + self.data.ledger[borrower].balance = borrowerTokensNew + self.data.ledger[liquidator].balance = liquidatorTokensNew """ The sender liquidates the borrowers collateral. @@ -388,7 +401,7 @@ def transfer(self, params): sp.set_type(params, sp.TRecord(from_=sp.TAddress, to_=sp.TAddress, value=sp.TNat).layout(("from_ as from", ("to_ as to", "value")))) sp.verify((params.from_ == sp.sender) | - (self.data.balances[params.from_].approvals[sp.sender] >= params.value), EC.CT_TRANSFER_NOT_APPROVED) + (self.data.ledger[params.from_].approvals[sp.sender] >= params.value), EC.CT_TRANSFER_NOT_APPROVED) self.verifyNotInternal() self.verifyTransferAllowed(params.from_, params.to_, params.value) self.transferInternal(sp.record( @@ -397,16 +410,16 @@ def transfer(self, params): def transferInternal(self, params): sp.set_type(params, sp.TRecord(from_=sp.TAddress, to_=sp.TAddress, value=sp.TNat, sender=sp.TAddress)) - sp.verify(self.data.balances[params.from_].balance >= + sp.verify(self.data.ledger[params.from_].balance >= params.value, EC.CT_INSUFFICIENT_BALANCE) - self.data.balances[params.from_].balance = sp.as_nat( - self.data.balances[params.from_].balance - params.value) - self.data.balances[params.to_].balance += params.value + self.data.ledger[params.from_].balance = sp.as_nat( + self.data.ledger[params.from_].balance - params.value) + self.data.ledger[params.to_].balance += params.value sp.if (params.from_ != params.sender): - self.data.balances[params.from_].approvals[params.sender] = sp.as_nat( - self.data.balances[params.from_].approvals[params.sender] - params.value) - sp.if self.data.balances[params.from_].approvals[params.sender] == 0: - del self.data.balances[params.from_].approvals[params.sender] + self.data.ledger[params.from_].approvals[params.sender] = sp.as_nat( + self.data.ledger[params.from_].approvals[params.sender] - params.value) + sp.if self.data.ledger[params.from_].approvals[params.sender] == 0: + del self.data.ledger[params.from_].approvals[params.sender] def verifyTransferAllowed(self, src_, dst_, transferTokens_): self.addAddressIfNecessary(dst_) @@ -417,9 +430,12 @@ def verifyTransferAllowed(self, src_, dst_, transferTokens_): sp.transfer(transferData, sp.mutez(0), c) def addAddressIfNecessary(self, address): - sp.if ~ self.data.balances.contains(address): - self.data.balances[address] = sp.record(balance=sp.nat(0), approvals={ - }, accountBorrows=sp.record(principal=sp.nat(0), interestIndex=sp.nat(0))) + sp.if ~ self.data.ledger.contains(address): + self.data.ledger[address] = sp.record(balance=sp.nat(0), approvals={ + }) + sp.if ~ self.data.borrows.contains(address): + self.data.borrows[address] = sp.record( + principal=sp.nat(0), interestIndex=sp.nat(0)) """ Approve `spender` to transfer up to `amount` from `sp.sender` @@ -435,17 +451,29 @@ def approve(self, params): self.verifyNotInternal() # check if max approvals reached if new entry in approvals - sp.verify((self.data.balances[sp.sender].approvals.contains(params.spender)) | ( - 1000 > sp.len(self.data.balances[sp.sender].approvals)), EC.CT_MAX_APPROVALS) + sp.verify((self.data.ledger[sp.sender].approvals.contains(params.spender)) | ( + 1000 > sp.len(self.data.ledger[sp.sender].approvals)), EC.CT_MAX_APPROVALS) - alreadyApproved = self.data.balances[sp.sender].approvals.get( + alreadyApproved = self.data.ledger[sp.sender].approvals.get( params.spender, 0) sp.verify((alreadyApproved == 0) | (params.value == 0), EC.CT_UNSAFE_ALLOWANCE_CHANGE) sp.if params.value == 0: - del self.data.balances[sp.sender].approvals[params.spender] + del self.data.ledger[sp.sender].approvals[params.spender] sp.else: - self.data.balances[sp.sender].approvals[params.spender] = params.value + self.data.ledger[sp.sender].approvals[params.spender] = params.value + + """ + Updates the contract metadata at specified key + params: + key: TString - The key to update + value: TBytes - The value to update with + """ + @sp.entry_point + def updateMetadata(self, params): + sp.set_type(params, sp.TRecord(key=sp.TString, value=sp.TBytes)) + self.verifyAdministrator() + self.data.metadata[params.key] = params.value """ Get the CToken balance of the account specified in `params` @@ -457,8 +485,8 @@ def approve(self, params): @sp.utils.view(sp.TNat) def getBalance(self, params): result = sp.local("result", 0) - sp.if self.data.balances.contains(params): - result.value = self.data.balances[params].balance + sp.if self.data.ledger.contains(params): + result.value = self.data.ledger[params].balance sp.result(result.value) """ @@ -471,8 +499,8 @@ def getBalance(self, params): @sp.onchain_view() def balanceOf(self, params): result = sp.local("result", 0) - sp.if self.data.balances.contains(params): - result.value = self.data.balances[params].balance + sp.if self.data.ledger.contains(params): + result.value = self.data.ledger[params].balance sp.result(result.value) """ @@ -490,7 +518,7 @@ def getBalanceOfUnderlying(self, params): sp.set_type(params, sp.TAddress) exchangeRate = self.makeExp(self.exchangeRateStoredImpl()) balance = self.mulScalarTruncate( - exchangeRate, self.data.balances[params].balance) + exchangeRate, self.data.ledger[params].balance) sp.result(balance) """ @@ -517,13 +545,13 @@ def getTotalSupply(self, params): @sp.utils.view(sp.TNat) def getAllowance(self, params): result = sp.local("result", 0) - sp.if self.data.balances.contains(params.owner): - sp.if self.data.balances[params.owner].approvals.contains(params.spender): - result.value = self.data.balances[params.owner].approvals[params.spender] + sp.if self.data.ledger.contains(params.owner): + sp.if self.data.ledger[params.owner].approvals.contains(params.spender): + result.value = self.data.ledger[params.owner].approvals[params.spender] sp.result(result.value) """ - Get a snapshot of the account's balances, and the cached exchange rate + Get a snapshot of the account's ledger, and the cached exchange rate dev: This is used by comptroller to more efficiently perform liquidity checks. dev: Do accrueInterest() before this function to get the up-to-date balance @@ -540,9 +568,9 @@ def helpAccountSnapshot(self, params): borrowBalance=sp.nat(0), exchangeRateMantissa=sp.nat(0) )) - sp.if self.data.balances.contains(params): + sp.if self.data.ledger.contains(params): self.verifyAccruedInterestRelevance() - accSnapshot.cTokenBalance = self.data.balances[params].balance + accSnapshot.cTokenBalance = self.data.ledger[params].balance accSnapshot.borrowBalance = self.getBorrowBalance(params) accSnapshot.exchangeRateMantissa = self.exchangeRateStoredImpl() return accSnapshot @@ -552,7 +580,7 @@ def getAccountSnapshot(self, params): sp.result(self.helpAccountSnapshot(params)) """ - Get a snapshot of the account's balances, and the cached exchange rate + Get a snapshot of the account's ledger, and the cached exchange rate dev: This is used by comptroller to more efficiently perform liquidity checks. dev: Do accrueInterest() before this function to get the up-to-date balance @@ -595,9 +623,9 @@ def borrowBalanceStoredView(self, params): def getBorrowBalance(self, account): borrowBalance = sp.local('borrowBalance', sp.nat(0)) - sp.if self.data.balances.contains(account): + sp.if self.data.borrows.contains(account): borrowSnapshot = sp.local( - 'borrowSnapshot', self.data.balances[account].accountBorrows) + 'borrowSnapshot', self.data.borrows[account]) sp.if borrowSnapshot.value.principal > 0: principalTimesIndex = borrowSnapshot.value.principal * self.data.borrowIndex borrowBalance.value = principalTimesIndex // borrowSnapshot.value.interestIndex diff --git a/contracts/CXTZ.py b/contracts/CXTZ.py index fff234f8..32071ff0 100644 --- a/contracts/CXTZ.py +++ b/contracts/CXTZ.py @@ -12,10 +12,10 @@ class CXTZ(CToken.CToken): - def __init__(self, comptroller_, interestRateModel_, administrator_): + def __init__(self, comptroller_, interestRateModel_, administrator_, metadata_, token_metadata_): initialExchangeRateMantissa = sp.nat(int(1e18)) CToken.CToken.__init__(self, comptroller_, interestRateModel_, - initialExchangeRateMantissa, administrator_) + initialExchangeRateMantissa, administrator_, metadata_, token_metadata_) def getCashImpl(self): return sp.utils.mutez_to_nat(sp.balance) diff --git a/contracts/Governance.py b/contracts/Governance.py index ee098954..ecaf24cb 100644 --- a/contracts/Governance.py +++ b/contracts/Governance.py @@ -187,6 +187,23 @@ def reduceReserves(self, params): "reduceReserves").open_some() sp.transfer(params.amount, sp.mutez(0), contract) + """ + Updates the contract metadata of the cToken at specified key with specified value + params: TRecord + cToken: TAddress - The address of CToken contract + key: TString - The key of the metadata to update + value: TBytes - The value to update the metadata with + """ + @sp.entry_point + def updateMetadata(self, params): + self.verifyAdministrator() + sp.set_type(params, sp.TRecord(cToken=sp.TAddress, + key=sp.TString, value=sp.TBytes)) + contract = sp.contract(sp.TRecord( + key=sp.TString, value=sp.TBytes), params.cToken, "updateMetadata").open_some() + sp.transfer(sp.record(key=params.key, value=params.value), + sp.mutez(0), contract) + # Comptroller functions """ diff --git a/contracts/interfaces/CTokenInterface.py b/contracts/interfaces/CTokenInterface.py index 69774e33..a2771167 100644 --- a/contracts/interfaces/CTokenInterface.py +++ b/contracts/interfaces/CTokenInterface.py @@ -153,6 +153,18 @@ def transfer(self, params): def approve(self, params): pass + """ + Updates the contract metadata at specified key + params: + key: TString - The key to update + value: TBytes - The value to update with + requirements: + Can be called only by the contract administrator + """ + @sp.entry_point + def updateMetadata(self, params): + pass + """ Get the current allowance from `owner` for `spender` diff --git a/contracts/interfaces/GovernanceInterface.py b/contracts/interfaces/GovernanceInterface.py index c9ee1773..d3ba1ae1 100644 --- a/contracts/interfaces/GovernanceInterface.py +++ b/contracts/interfaces/GovernanceInterface.py @@ -91,6 +91,17 @@ def setReserveFactor(self, params): def reduceReserves(self, params): pass + """ + Updates the contract metadata of the cToken at specified key with specified value + params: TRecord + cToken: TAddress - The address of CToken contract + key: TString - The key of the metadata to update + value: TBytes - The value to update the metadata with + """ + @sp.entry_point + def updateMetadata(self, params): + pass + # Comptroller functions """ diff --git a/contracts/tests/CFA12Test.py b/contracts/tests/CFA12Test.py index eb80870a..295ab56a 100644 --- a/contracts/tests/CFA12Test.py +++ b/contracts/tests/CFA12Test.py @@ -1,4 +1,5 @@ import smartpy as sp +import json CFA12 = sp.io.import_script_from_url("file:contracts/CFA12.py") IRM = sp.io.import_script_from_url("file:contracts/tests/mock/InterestRateModelMock.py") @@ -41,6 +42,23 @@ def test(): interestRateModel_=irm.address, initialExchangeRateMantissa_=sp.nat(exchange_rate), administrator_=admin.address, + metadata_=sp.big_map({ + "": sp.utils.bytes_of_string("tezos-storage:data"), + "data": sp.utils.bytes_of_string(json.dumps({ + "name": "...", + "description": "...", + "version": "1.0.0", + "authors": ["ewqenqjw"], + "homepage": "https://some-website.com", + "interfaces": ["TZIP-007"], + "license": {"name": "..."} + })) + }), + token_metadata_={ + "name": sp.utils.bytes_of_string("Compound XTZ"), + "symbol": sp.utils.bytes_of_string("fXTZ"), + "decimals": sp.utils.bytes_of_string("6"), + }, fa1_2_TokenAddress_ = fa12.address) scenario += c1 @@ -54,13 +72,13 @@ def test(): scenario += fa12.approve(sp.record(spender = c1.address, value = 100)).run(sender=alice) DataRelevance.updateAccrueInterest(scenario, bLevel, alice, c1) scenario += c1.mint(100).run(sender=alice, level=bLevel.current()) - scenario.verify(c1.data.balances[alice.address].balance == 100) + scenario.verify(c1.data.ledger[alice.address].balance == 100) scenario.h3("Second mint") scenario += fa12.mint(sp.record(address = admin.address, value = 10)) scenario += fa12.approve(sp.record(spender = c1.address, value = 10)).run(sender=admin) DataRelevance.updateAccrueInterest(scenario, bLevel, alice, c1) scenario += c1.mint(10).run(sender=admin, level=bLevel.current()) - scenario.verify(c1.data.balances[admin.address].balance == 10) + scenario.verify(c1.data.ledger[admin.address].balance == 10) scenario.h2("Check getCash") scenario.h3("Before accrueInterest") diff --git a/contracts/tests/CFA2Test.py b/contracts/tests/CFA2Test.py index fb7faa70..dd8e8510 100644 --- a/contracts/tests/CFA2Test.py +++ b/contracts/tests/CFA2Test.py @@ -1,4 +1,5 @@ import smartpy as sp +import json CFA2 = sp.io.import_script_from_url("file:contracts/CFA2.py") IRM = sp.io.import_script_from_url("file:contracts/tests/mock/InterestRateModelMock.py") @@ -48,6 +49,23 @@ def test(): interestRateModel_=irm.address, initialExchangeRateMantissa_=sp.nat(exchange_rate), administrator_=admin.address, + metadata_=sp.big_map({ + "": sp.utils.bytes_of_string("tezos-storage:data"), + "data": sp.utils.bytes_of_string(json.dumps({ + "name": "...", + "description": "...", + "version": "1.0.0", + "authors": ["ewqenqjw"], + "homepage": "https://some-website.com", + "interfaces": ["TZIP-007"], + "license": {"name": "..."} + })) + }), + token_metadata_={ + "name": sp.utils.bytes_of_string("CFA2"), + "symbol": sp.utils.bytes_of_string("cFA2"), + "decimals": sp.utils.bytes_of_string("6"), + }, fa2_TokenAddress_ = fa2.address, tokenId_ = tokenId) scenario += c1 @@ -71,11 +89,11 @@ def test(): ]).run(sender = admin) DataRelevance.updateAccrueInterest(scenario, bLevel, alice, c1) scenario += c1.mint(100).run(sender=alice, level=bLevel.current()) - scenario.verify(c1.data.balances[alice.address].balance == 100) + scenario.verify(c1.data.ledger[alice.address].balance == 100) scenario.h3("Second mint") DataRelevance.updateAccrueInterest(scenario, bLevel, alice, c1) scenario += c1.mint(100).run(sender=alice, level=bLevel.current()) - scenario.verify(c1.data.balances[alice.address].balance == 200) + scenario.verify(c1.data.ledger[alice.address].balance == 200) scenario.h3("Try mint with no cash") scenario += c1.mint(100).run(sender=alice, level=bLevel.next(), valid=False) diff --git a/contracts/tests/CTokenTest.py b/contracts/tests/CTokenTest.py index 15d98d4f..61779362 100644 --- a/contracts/tests/CTokenTest.py +++ b/contracts/tests/CTokenTest.py @@ -1,4 +1,5 @@ import smartpy as sp +import json CToken = sp.io.import_script_from_url("file:contracts/CToken.py") IRM = sp.io.import_script_from_url("file:contracts/tests/mock/InterestRateModelMock.py") @@ -10,8 +11,8 @@ class TestCToken(CToken.CToken): - def __init__(self, comptroller_, interestRateModel_, initialExchangeRateMantissa_, administrator_, **extra_storage): - CToken.CToken.__init__(self, comptroller_, interestRateModel_, initialExchangeRateMantissa_, administrator_, + def __init__(self, comptroller_, interestRateModel_, initialExchangeRateMantissa_, administrator_, metadata_, token_metadata_, **extra_storage): + CToken.CToken.__init__(self, comptroller_, interestRateModel_, initialExchangeRateMantissa_, administrator_, metadata_, token_metadata_, accCTokenBalance=sp.nat(0), accBorrowBalance=sp.nat(0), accExchangeRateMantissa=sp.nat(0)) def getCashImpl(self): @@ -67,10 +68,27 @@ def test(): scenario += cmpt irm = IRM.InterestRateModelMock(borrowRate_=sp.nat(80000000000), supplyRate_=sp.nat(180000000000)) scenario += irm - c1 = TestCToken(comptroller_=cmpt.address, - interestRateModel_=irm.address, + c1 = TestCToken(comptroller_=cmpt.address, + interestRateModel_=irm.address, initialExchangeRateMantissa_=sp.nat(exchange_rate), - administrator_=admin.address) + administrator_=admin.address, + metadata_=sp.big_map({ + "": sp.utils.bytes_of_string("tezos-storage:data"), + "data": sp.utils.bytes_of_string(json.dumps({ + "name": "...", + "description": "...", + "version": "1.0.0", + "authors": ["ewqenqjw"], + "homepage": "https://some-website.com", + "interfaces": ["TZIP-007"], + "license": {"name": "..."} + })) + }), + token_metadata_={ + "name": sp.utils.bytes_of_string("Compound token"), + "symbol": sp.utils.bytes_of_string("cToken"), + "decimals": sp.utils.bytes_of_string("x"), + }) scenario += c1 @@ -86,7 +104,7 @@ def test(): scenario.h2("Test mint") scenario.h3("Mint allowed") DataRelevance.validateAccrueInterestRelevance(scenario, "mint", bLevel, alice, c1, c1.mint, 100) - scenario.verify(c1.data.balances[alice.address].balance == sp.nat(100 * ctoken_decimals)) + scenario.verify(c1.data.ledger[alice.address].balance == sp.nat(100 * ctoken_decimals)) scenario.h3("Mint not allowed") scenario += cmpt.setMintAllowed(sp.bool(False)) DataRelevance.updateAccrueInterest(scenario, bLevel, alice, c1) @@ -95,15 +113,15 @@ def test(): scenario += cmpt.setMintAllowed(sp.bool(True)) DataRelevance.updateAccrueInterest(scenario, bLevel, alice, c1) scenario += c1.mint(1000).run(sender=bob, level=bLevel.current()) - scenario.verify(c1.data.balances[bob.address].balance == sp.nat(1000 * ctoken_decimals)) + scenario.verify(c1.data.ledger[bob.address].balance == sp.nat(1000 * ctoken_decimals)) scenario.h3("Try mint in callback") scenario += c1.getCash(sp.pair(sp.unit, c1.typed.mint)).run(sender=alice, level=bLevel.next(), valid=False) scenario.h2("Test Borrow") scenario.h3("Borrow allowed") DataRelevance.validateAllRelevance(scenario, "borrow", bLevel, carl, c1, c1.borrow, 10, cmpt, c1.address, carl.address) - scenario.verify(c1.data.balances[carl.address].balance == sp.nat(0)) - scenario.verify(c1.data.balances[carl.address].accountBorrows.principal == sp.nat(10)) + scenario.verify(c1.data.ledger[carl.address].balance == sp.nat(0)) + scenario.verify(c1.data.borrows[carl.address].principal == sp.nat(10)) scenario.h3("Borrow not allowed") scenario += cmpt.setBorrowAllowed(sp.bool(False)) DataRelevance.updateAccrueInterest(scenario, bLevel, alice, c1) @@ -112,8 +130,8 @@ def test(): DataRelevance.updateAllRelevance(scenario, bLevel, carl, c1, cmpt, c1.address, carl.address) scenario += cmpt.setBorrowAllowed(sp.bool(True)) scenario += c1.borrow(10).run(sender=alice, level=bLevel.current()) - scenario.verify(c1.data.balances[alice.address].balance == sp.nat(100 * ctoken_decimals)) - scenario.verify(c1.data.balances[alice.address].accountBorrows.principal == sp.nat(10)) + scenario.verify(c1.data.ledger[alice.address].balance == sp.nat(100 * ctoken_decimals)) + scenario.verify(c1.data.borrows[alice.address].principal == sp.nat(10)) scenario.h3("Try borrow with insufficient cash") DataRelevance.updateAccrueInterest(scenario, bLevel, alice, c1) scenario += c1.borrow(1100 * ctoken_decimals + 1).run(sender=carl, level=bLevel.current(), valid=False) @@ -123,7 +141,7 @@ def test(): scenario.h2("Test Redeem") scenario.h3("Redeem allowed") DataRelevance.validateAllRelevance(scenario, "redeem", bLevel, alice, c1, c1.redeem, 50 * ctoken_decimals, cmpt, c1.address, alice.address) - scenario.verify(c1.data.balances[alice.address].balance == sp.nat(50 * ctoken_decimals)) + scenario.verify(c1.data.ledger[alice.address].balance == sp.nat(50 * ctoken_decimals)) scenario.h3("Redeem not allowed") scenario += cmpt.setRedeemAllowed(sp.bool(False)) DataRelevance.updateAllRelevance(scenario, bLevel, carl, c1, cmpt, c1.address, carl.address) @@ -132,14 +150,14 @@ def test(): DataRelevance.updateAllRelevance(scenario, bLevel, carl, c1, cmpt, c1.address, carl.address) scenario += cmpt.setRedeemAllowed(sp.bool(True)) scenario += c1.redeem(10 * ctoken_decimals).run(sender=alice, level=bLevel.current()) - scenario.verify(c1.data.balances[alice.address].balance == sp.nat(40 * ctoken_decimals)) + scenario.verify(c1.data.ledger[alice.address].balance == sp.nat(40 * ctoken_decimals)) scenario.h3("Try redeem with insufficient balance") DataRelevance.updateAllRelevance(scenario, bLevel, carl, c1, cmpt, c1.address, carl.address) scenario += c1.redeem(50 * ctoken_decimals).run(sender=alice, level=bLevel.current(), valid=False) scenario.h3("Redeem underlying") DataRelevance.updateAllRelevance(scenario, bLevel, carl, c1, cmpt, c1.address, carl.address) scenario += c1.redeemUnderlying(10).run(sender=alice, level=bLevel.current()) - scenario.verify(c1.data.balances[alice.address].balance == sp.nat(30188680)) # due to exchange rate changes: 10 underlying < 10 000 000 CToken + scenario.verify(c1.data.ledger[alice.address].balance == sp.nat(30188680)) # due to exchange rate changes: 10 underlying < 10 000 000 CToken scenario.h3("Try redeem in callback") scenario += c1.getCash(sp.pair(sp.unit, c1.typed.redeem)).run(sender=alice, level=bLevel.next(), valid=False) scenario.h3("Try redeem underlying in callback") @@ -148,7 +166,7 @@ def test(): scenario.h2("Test Repay borrow") scenario.h3("Repay borrow allowed") DataRelevance.validateAccrueInterestRelevance(scenario, "repayBorrow", bLevel, alice, c1, c1.repayBorrow, 1) - scenario.verify(c1.data.balances[alice.address].accountBorrows.principal == sp.nat(9)) + scenario.verify(c1.data.borrows[alice.address].principal == sp.nat(9)) scenario.h3("Repay borrow not allowed") scenario += cmpt.setRepayBorrowAllowed(sp.bool(False)) DataRelevance.updateAccrueInterest(scenario, bLevel, carl, c1) @@ -157,16 +175,16 @@ def test(): DataRelevance.updateAccrueInterest(scenario, bLevel, carl, c1) scenario += cmpt.setRepayBorrowAllowed(sp.bool(True)) scenario += c1.repayBorrow(1).run(sender=alice, level=bLevel.current()) - scenario.verify(c1.data.balances[alice.address].accountBorrows.principal == sp.nat(8)) + scenario.verify(c1.data.borrows[alice.address].principal == sp.nat(8)) scenario.h3("Repay borrow behalf") DataRelevance.updateAccrueInterest(scenario, bLevel, carl, c1) scenario += c1.repayBorrowBehalf(sp.record(borrower=alice.address, repayAmount=sp.nat(1))).run(sender=bob, level=bLevel.current()) - scenario.verify(c1.data.balances[alice.address].accountBorrows.principal == sp.nat(7)) + scenario.verify(c1.data.borrows[alice.address].principal == sp.nat(7)) scenario.h3("Repay more than borrowed") DataRelevance.updateAccrueInterest(scenario, bLevel, carl, c1) scenario += c1.repayBorrow(1007).run(sender=alice, level=bLevel.current()) - scenario.show(c1.data.balances[alice.address].accountBorrows.principal) - scenario.verify(c1.data.balances[alice.address].accountBorrows.principal == sp.nat(0)) + scenario.show(c1.data.borrows[alice.address].principal) + scenario.verify(c1.data.borrows[alice.address].principal == sp.nat(0)) scenario.h3("Try repayBorrow in callback") scenario += c1.getCash(sp.pair(sp.unit, c1.typed.redeem)).run(sender=alice, level=bLevel.current(), valid=False) @@ -185,7 +203,7 @@ def test(): scenario += c1.getAllowance(sp.pair(sp.record(owner=carl.address, spender=alice.address), view_result.typed.targetNat)).run(sender=carl, level=bLevel.next()) scenario.verify_equal(view_result.data.last, sp.some(100)) scenario += c1.transfer(from_=carl.address, to_=alice.address, value=100).run(sender=alice, level=bLevel.next()) - scenario.verify(c1.data.balances[carl.address].balance == sp.nat(0)) + scenario.verify(c1.data.ledger[carl.address].balance == sp.nat(0)) scenario.h2("Admin functions") scenario.h3("Pending governance") diff --git a/contracts/tests/CXTZTest.py b/contracts/tests/CXTZTest.py index 78002856..ee74f955 100644 --- a/contracts/tests/CXTZTest.py +++ b/contracts/tests/CXTZTest.py @@ -1,4 +1,5 @@ import smartpy as sp +import json CXTZ = sp.io.import_script_from_url("file:contracts/CXTZ.py") IRM = sp.io.import_script_from_url("file:contracts/tests/mock/InterestRateModelMock.py") @@ -37,20 +38,37 @@ def test(): view_result = RV.ViewerNat() scenario += view_result - c1 = CXTZ.CXTZ(comptroller_=cmpt.address, - interestRateModel_=irm.address, - administrator_=admin.address) + c1 = CXTZ.CXTZ(comptroller_=cmpt.address, + interestRateModel_=irm.address, + administrator_=admin.address, + metadata_=sp.big_map({ + "": sp.utils.bytes_of_string("tezos-storage:data"), + "data": sp.utils.bytes_of_string(json.dumps({ + "name": "...", + "description": "...", + "version": "1.0.0", + "authors": ["ewqenqjw"], + "homepage": "https://some-website.com", + "interfaces": ["TZIP-007"], + "license": {"name": "..."} + })) + }), + token_metadata_={ + "name": sp.utils.bytes_of_string("Compound XTZ"), + "symbol": sp.utils.bytes_of_string("fXTZ"), + "decimals": sp.utils.bytes_of_string("6"), + }) scenario += c1 scenario.h2("mint + transferIn") scenario.h3("first mint") DataRelevance.updateAccrueInterest(scenario, bLevel, alice, c1) scenario += c1.mint(777).run(sender=alice, level=bLevel.current(), amount=sp.mutez(777)) - scenario.verify(c1.data.balances[alice.address].balance == sp.nat(777)) + scenario.verify(c1.data.ledger[alice.address].balance == sp.nat(777)) scenario.h3("second mint") DataRelevance.updateAccrueInterest(scenario, bLevel, alice, c1) scenario += c1.mint(20).run(sender=admin, level=bLevel.current(), amount=sp.mutez(20)) - scenario.verify(c1.data.balances[admin.address].balance == sp.nat(20)) + scenario.verify(c1.data.ledger[admin.address].balance == sp.nat(20)) scenario.h2("getCash") scenario += c1.getCash(sp.pair(sp.unit, view_result.typed.targetNat)).run(sender=alice, level=bLevel.next()) diff --git a/contracts/tests/GovernanceTest.py b/contracts/tests/GovernanceTest.py index 56dd59c3..a09dd8e3 100644 --- a/contracts/tests/GovernanceTest.py +++ b/contracts/tests/GovernanceTest.py @@ -1,4 +1,5 @@ import smartpy as sp +import json GOV = sp.io.import_script_from_url("file:contracts/Governance.py") BlockLevel = sp.io.import_script_from_url("file:contracts/tests/utils/BlockLevel.py") @@ -48,11 +49,46 @@ def test(): interestRateModel_=irm.address, initialExchangeRateMantissa_=sp.nat(int(1e12)), administrator_=governor.address, + metadata_=sp.big_map({ + "": sp.utils.bytes_of_string("tezos-storage:data"), + "data": sp.utils.bytes_of_string(json.dumps({ + "name": "...", + "description": "...", + "version": "1.0.0", + "authors": ["ewqenqjw"], + "homepage": "https://some-website.com", + "interfaces": ["TZIP-007"], + "license": {"name": "..."} + })) + }), + token_metadata_={ + "name": sp.utils.bytes_of_string("Compound XTZ"), + "symbol": sp.utils.bytes_of_string("fXTZ"), + "decimals": sp.utils.bytes_of_string("6"), + }, fa1_2_TokenAddress_ = fa12Target.address) scenario += cfa12 - cxtz = CXTZ.CXTZ(comptroller_=cmpt.address, - interestRateModel_=irm.address, - administrator_=governor.address) + cxtz = CXTZ.CXTZ(comptroller_=cmpt.address, + interestRateModel_=irm.address, + administrator_=governor.address, + metadata_=sp.big_map({ + "": sp.utils.bytes_of_string("tezos-storage:data"), + "data": sp.utils.bytes_of_string(json.dumps({ + "name": "...", + "description": "...", + "version": "1.0.0", + "authors": ["ewqenqjw"], + "homepage": "https://some-website.com", + "interfaces": ["TZIP-007"], + "license": {"name": "..."} + })) + }), + token_metadata_={ + "name": sp.utils.bytes_of_string("Compound XTZ"), + "symbol": sp.utils.bytes_of_string("fXTZ"), + "decimals": sp.utils.bytes_of_string("6"), + }, + ) scenario += cxtz oracle = OracleMock.OracleMock() scenario += oracle @@ -111,6 +147,19 @@ def testCToken(scenario, ctoken, bLevel, alice, admin, governor, cmpt, irm, orac arg = sp.record(cToken = ctoken.address, newReserveFactor = sp.nat(2)) TestAdminFunctionality.checkAdminRequirementH4(scenario, "set reserve factor", bLevel, admin, alice, governor.setReserveFactor, arg) scenario.verify(ctoken.data.reserveFactorMantissa == arg.newReserveFactor) + + scenario.h3("Update contract metadata") + arg = sp.record(cToken=ctoken.address, key=sp.string("data"), value=sp.utils.bytes_of_string(json.dumps({ + "name": "New name", + "description": "new description", + "version": "1.0.0", + "authors": ["ewqenqjw"], + "homepage": "https://some-website.com", + "interfaces": ["TZIP-007"], + "license": {"name": "my token"} + }))) + TestAdminFunctionality.checkAdminRequirementH4(scenario, "update contract metadata", bLevel, admin, alice, governor.updateMetadata, arg) + scenario.verify(ctoken.data.metadata[arg.key] == arg.value) def testCxtzReserves(scenario, cxtz, bLevel, alice, admin, governor): scenario.h3("Add reserves to reduce") diff --git a/deploy/compile_targets/CompileCBTCtz.py b/deploy/compile_targets/CompileCBTCtz.py index 819d125e..36bfcc44 100644 --- a/deploy/compile_targets/CompileCBTCtz.py +++ b/deploy/compile_targets/CompileCBTCtz.py @@ -1,4 +1,5 @@ import smartpy as sp +import json CFG = sp.io.import_script_from_url("file:deploy/compile_targets/Config.py") CFA2 = sp.io.import_script_from_url("file:contracts/CFA2.py") @@ -11,6 +12,24 @@ interestRateModel_ = sp.address(CFG.deployResult.CFA2_IRM), initialExchangeRateMantissa_ = sp.nat(CFG.CFA2.initialExchangeRateMantissa), administrator_ = sp.address(CFG.deployResult.Governance), + # specify metadata before compilation + metadata_ = sp.big_map({ + "": sp.utils.bytes_of_string("tezos-storage:data"), + "data": sp.utils.bytes_of_string(json.dumps({ + "name": "...", + "description": "...", + "version": "1.0.0", + "authors": ["..."], + "homepage": "https://some-website.com", + "interfaces": ["TZIP-007"], + "license": {"name": "..."} + })) + }), + token_metadata_ = { + "name": sp.utils.bytes_of_string("Compound XTZ"), + "symbol": sp.utils.bytes_of_string("fXTZ"), + "decimals": sp.utils.bytes_of_string("..."), + }, fa2_TokenAddress_ = sp.address(CFG.deployResult.BTCtz), tokenId_ = sp.nat(CFG.CFA2.tokenId) )) diff --git a/deploy/compile_targets/CompileCEthtz.py b/deploy/compile_targets/CompileCEthtz.py index a7b63c6f..c5e0f074 100644 --- a/deploy/compile_targets/CompileCEthtz.py +++ b/deploy/compile_targets/CompileCEthtz.py @@ -1,4 +1,5 @@ import smartpy as sp +import json CFG = sp.io.import_script_from_url("file:deploy/compile_targets/Config.py") CFA12 = sp.io.import_script_from_url("file:contracts/CFA12.py") @@ -11,5 +12,23 @@ interestRateModel_ = sp.address(CFG.deployResult.CFA12_IRM), initialExchangeRateMantissa_ = sp.nat(CFG.CFA2.initialExchangeRateMantissa), administrator_ = sp.address(CFG.deployResult.Governance), + # specify metadata before compilation + metadata_ = sp.big_map({ + "": sp.utils.bytes_of_string("tezos-storage:data"), + "data": sp.utils.bytes_of_string(json.dumps({ + "name": "...", + "description": "...", + "version": "1.0.0", + "authors": ["..."], + "homepage": "https://some-website.com", + "interfaces": ["TZIP-007"], + "license": {"name": "..."} + })) + }), + token_metadata_ = { + "name": sp.utils.bytes_of_string("Compound XTZ"), + "symbol": sp.utils.bytes_of_string("fXTZ"), + "decimals": sp.utils.bytes_of_string("..."), + }, fa1_2_TokenAddress_ = sp.address(CFG.deployResult.ETHtz) )) diff --git a/deploy/compile_targets/CompileCUSDt.py b/deploy/compile_targets/CompileCUSDt.py index 061ee80f..661ffec2 100644 --- a/deploy/compile_targets/CompileCUSDt.py +++ b/deploy/compile_targets/CompileCUSDt.py @@ -1,4 +1,5 @@ import smartpy as sp +import json CFG = sp.io.import_script_from_url("file:deploy/compile_targets/Config.py") CFA2 = sp.io.import_script_from_url("file:contracts/CFA2.py") @@ -11,6 +12,24 @@ interestRateModel_ = sp.address(CFG.deployResult.CFA2_IRM), initialExchangeRateMantissa_ = sp.nat(CFG.CFA2.initialExchangeRateMantissa), administrator_ = sp.address(CFG.deployResult.Governance), + # specify metadata before compilation + metadata_ = sp.big_map({ + "": sp.utils.bytes_of_string("tezos-storage:data"), + "data": sp.utils.bytes_of_string(json.dumps({ + "name": "...", + "description": "...", + "version": "1.0.0", + "authors": ["..."], + "homepage": "https://some-website.com", + "interfaces": ["TZIP-007"], + "license": {"name": "..."} + })) + }), + token_metadata_ = { + "name": sp.utils.bytes_of_string("..."), + "symbol": sp.utils.bytes_of_string("..."), + "decimals": sp.utils.bytes_of_string("..."), + }, fa2_TokenAddress_ = sp.address(CFG.deployResult.USDt), tokenId_ = sp.nat(CFG.CFA2.tokenId) )) diff --git a/deploy/compile_targets/CompileCUSDtz.py b/deploy/compile_targets/CompileCUSDtz.py index f1db8699..108f482e 100644 --- a/deploy/compile_targets/CompileCUSDtz.py +++ b/deploy/compile_targets/CompileCUSDtz.py @@ -1,4 +1,5 @@ import smartpy as sp +import json CFG = sp.io.import_script_from_url("file:deploy/compile_targets/Config.py") CFA12 = sp.io.import_script_from_url("file:contracts/CFA12.py") @@ -11,5 +12,23 @@ interestRateModel_ = sp.address(CFG.deployResult.CFA12_IRM), initialExchangeRateMantissa_ = sp.nat(CFG.CFA2.initialExchangeRateMantissa), administrator_ = sp.address(CFG.deployResult.Governance), + # specify metadata before compilation + metadata_ = sp.big_map({ + "": sp.utils.bytes_of_string("tezos-storage:data"), + "data": sp.utils.bytes_of_string(json.dumps({ + "name": "...", + "description": "...", + "version": "1.0.0", + "authors": ["..."], + "homepage": "https://some-website.com", + "interfaces": ["TZIP-007"], + "license": {"name": "..."} + })) + }), + token_metadata_ = { + "name": sp.utils.bytes_of_string("..."), + "symbol": sp.utils.bytes_of_string("..."), + "decimals": sp.utils.bytes_of_string("..."), + }, fa1_2_TokenAddress_ = sp.address(CFG.deployResult.USDtz) )) diff --git a/deploy/compile_targets/CompileCWTZ.py b/deploy/compile_targets/CompileCWTZ.py index 3894f177..65682f47 100644 --- a/deploy/compile_targets/CompileCWTZ.py +++ b/deploy/compile_targets/CompileCWTZ.py @@ -1,4 +1,5 @@ import smartpy as sp +import json CFG = sp.io.import_script_from_url("file:deploy/compile_targets/Config.py") CFA2 = sp.io.import_script_from_url("file:contracts/CFA2.py") @@ -11,6 +12,24 @@ interestRateModel_ = sp.address(CFG.deployResult.CFA2_IRM), initialExchangeRateMantissa_ = sp.nat(CFG.CFA2.initialExchangeRateMantissa), administrator_ = sp.address(CFG.deployResult.Governance), + # specify metadata before compilation + metadata_ = sp.big_map({ + "": sp.utils.bytes_of_string("tezos-storage:data"), + "data": sp.utils.bytes_of_string(json.dumps({ + "name": "...", + "description": "...", + "version": "1.0.0", + "authors": ["..."], + "homepage": "https://some-website.com", + "interfaces": ["TZIP-007"], + "license": {"name": "..."} + })) + }), + token_metadata_ = { + "name": sp.utils.bytes_of_string("..."), + "symbol": sp.utils.bytes_of_string("..."), + "decimals": sp.utils.bytes_of_string("..."), + }, fa2_TokenAddress_ = sp.address(CFG.deployResult.WTZ), tokenId_ = sp.nat(CFG.CFA2.tokenId) )) diff --git a/deploy/compile_targets/CompileCXTZ.py b/deploy/compile_targets/CompileCXTZ.py index 57e51fba..557c24d0 100644 --- a/deploy/compile_targets/CompileCXTZ.py +++ b/deploy/compile_targets/CompileCXTZ.py @@ -1,4 +1,5 @@ import smartpy as sp +import json CFG = sp.io.import_script_from_url("file:deploy/compile_targets/Config.py") CXTZ = sp.io.import_script_from_url("file:contracts/CXTZ.py") @@ -10,4 +11,22 @@ comptroller_ = sp.address(CFG.deployResult.Comptroller), interestRateModel_ = sp.address(CFG.deployResult.CXTZ_IRM), administrator_ = sp.address(CFG.deployResult.Governance), - )) + # specify metadata before compilation + metadata_ = sp.big_map({ + "": sp.utils.bytes_of_string("tezos-storage:data"), + "data": sp.utils.bytes_of_string(json.dumps({ + "name": "Compount XTZ contract", + "description": "...", + "version": "1.0.0", + "authors": ["..."], + "homepage": "https://some-website.com", + "interfaces": ["TZIP-007"], + "license": {"name": "..."} + })) + }), + token_metadata_ = { + "name": sp.utils.bytes_of_string("Compound XTZ"), + "symbol": sp.utils.bytes_of_string("fXTZ"), + "decimals": sp.utils.bytes_of_string("6"), + } +)) diff --git a/deploy/compile_targets/CompileCoXTZ.py b/deploy/compile_targets/CompileCoXTZ.py index 65b35c71..7e6b74d5 100644 --- a/deploy/compile_targets/CompileCoXTZ.py +++ b/deploy/compile_targets/CompileCoXTZ.py @@ -1,4 +1,5 @@ import smartpy as sp +import json CFG = sp.io.import_script_from_url("file:deploy/compile_targets/Config.py") CFA12 = sp.io.import_script_from_url("file:contracts/CFA12.py") @@ -11,5 +12,23 @@ interestRateModel_ = sp.address(CFG.deployResult.CFA12_IRM), initialExchangeRateMantissa_ = sp.nat(CFG.CFA2.initialExchangeRateMantissa), administrator_ = sp.address(CFG.deployResult.Governance), + # specify metadata before compilation + metadata_ = sp.big_map({ + "": sp.utils.bytes_of_string("tezos-storage:data"), + "data": sp.utils.bytes_of_string(json.dumps({ + "name": "...", + "description": "...", + "version": "1.0.0", + "authors": ["..."], + "homepage": "https://some-website.com", + "interfaces": ["TZIP-007"], + "license": {"name": "..."} + })) + }), + token_metadata_ = { + "name": sp.utils.bytes_of_string("..."), + "symbol": sp.utils.bytes_of_string("..."), + "decimals": sp.utils.bytes_of_string("..."), + }, fa1_2_TokenAddress_ = sp.address(CFG.deployResult.oXTZ) )) diff --git a/deploy/compile_targets/CompileTzBTC.py b/deploy/compile_targets/CompileTzBTC.py index 13032960..5a1b04cd 100644 --- a/deploy/compile_targets/CompileTzBTC.py +++ b/deploy/compile_targets/CompileTzBTC.py @@ -1,4 +1,5 @@ import smartpy as sp +import json CFG = sp.io.import_script_from_url("file:deploy/compile_targets/Config.py") CFA12 = sp.io.import_script_from_url("file:contracts/CFA12.py") @@ -11,5 +12,23 @@ interestRateModel_ = sp.address(CFG.deployResult.CFA12_IRM), initialExchangeRateMantissa_ = sp.nat(CFG.CFA2.initialExchangeRateMantissa), administrator_ = sp.address(CFG.deployResult.Governance), + # specify metadata before deployment + metadata_ = sp.big_map({ + "": sp.utils.bytes_of_string("tezos-storage:data"), + "data": sp.utils.bytes_of_string(json.dumps({ + "name": "...", + "description": "...", + "version": "1.0.0", + "authors": ["..."], + "homepage": "https://some-website.com", + "interfaces": ["TZIP-007"], + "license": {"name": "..."} + })) + }), + token_metadata_ = { + "name": sp.utils.bytes_of_string("..."), + "symbol": sp.utils.bytes_of_string("..."), + "decimals": sp.utils.bytes_of_string("..."), + }, fa1_2_TokenAddress_ = sp.address(CFG.deployResult.tzBTC) ))