Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename vars. Update test to avoid errors. #1050

Merged
merged 5 commits into from
Jan 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions src/masternodes/mn_checks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1431,19 +1431,19 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor
return std::move(resVal);
}

CDataStructureV0 premiumKey{AttributeTypes::Param, ParamIDs::DFIP2201, DFIP2201Keys::Premium};
CAmount premium{2500000};
CDataStructureV0 feePctKey{AttributeTypes::Param, ParamIDs::DFIP2201, DFIP2201Keys::Premium};
prasannavl marked this conversation as resolved.
Show resolved Hide resolved
CAmount feePct{2500000};
try {
const auto& value = attrs.at(premiumKey);
const auto& value = attrs.at(feePctKey);
auto valueV0 = boost::get<const CValueV0>(&value);
if (valueV0) {
if (auto storedPremium = boost::get<const CAmount>(valueV0)) {
premium = *storedPremium;
if (auto storedFeePct = boost::get<const CAmount>(valueV0)) {
feePct = *storedFeePct;
}
}
} catch (const std::out_of_range&) {}

const auto& btcPrice = MultiplyAmounts(resVal.val.get(), premium + COIN);
const auto& btcPrice = MultiplyAmounts(resVal.val.get(), feePct + COIN);

resVal = mnview.GetValidatedIntervalPrice(dfiUsd, useNextPrice, requireLivePrice);
if (!resVal) {
Expand Down Expand Up @@ -3056,6 +3056,13 @@ class CCustomTxRevertVisitor : public CCustomTxVisitor
return EraseHistory(obj.from);
}

Res operator()(const CSmartContractMessage& obj) const {
for (const auto& account : obj.accounts) {
EraseHistory(account.first);
}
return Res::Ok();
}

Res operator()(const CAnyAccountsToAccountsMessage& obj) const {
for (const auto& account : obj.to) {
EraseHistory(account.first);
Expand Down
118 changes: 47 additions & 71 deletions test/functional/feature_smart_contracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,34 +13,29 @@

class SmartContractTest(DefiTestFramework):
def set_test_params(self):
self.num_nodes = 2
self.num_nodes = 1
self.setup_clean_chain = True
self.extra_args = [['-txnotokens=0', '-amkheight=1', '-bayfrontheight=1', '-eunosheight=1', '-fortcanningheight=1', '-fortcanninghillheight=1010', '-subsidytest=1', '-txindex=1', '-jellyfish_regtest=1'],
['-txnotokens=0', '-amkheight=1', '-bayfrontheight=1', '-eunosheight=1', '-fortcanningheight=1', '-fortcanninghillheight=1010', '-subsidytest=1', '-txindex=1', '-jellyfish_regtest=1']]
self.extra_args = [['-txnotokens=0', '-amkheight=1', '-bayfrontheight=1', '-eunosheight=1', '-fortcanningheight=1', '-fortcanninghillheight=1010', '-subsidytest=1', '-txindex=1', '-jellyfish_regtest=1']]

def rollback(self, count):
block = self.nodes[0].getblockhash(count)
self.nodes[0].invalidateblock(block)
self.nodes[1].invalidateblock(block)
self.nodes[0].clearmempool()
self.nodes[1].clearmempool()
self.sync_blocks()

def run_test(self):
self.nodes[0].generate(1000)
self.sync_blocks()

address = self.nodes[1].getnewaddress("", "legacy")
invalid_address = self.nodes[0].getnewaddress("", "legacy")
address = self.nodes[0].getnewaddress("", "legacy")
invalid_address = 'mrV4kYRhyrfiCcpfXDSZuhe56kCQu84gqh'
dfi_amount = 1000
btc_amount = 1
dfip = 'dbtcdfiswap'

# Check invalid calls
assert_raises_rpc_error(-5, 'Incorrect authorization for {}'.format(invalid_address), self.nodes[1].executesmartcontract, dfip, str(btc_amount) + '@2', invalid_address)
assert_raises_rpc_error(-5, 'Incorrect authorization for {}'.format(invalid_address), self.nodes[0].executesmartcontract, dfip, str(btc_amount) + '@2', invalid_address)
assert_raises_rpc_error(-4, 'Insufficient funds', self.nodes[0].executesmartcontract, dfip, str(dfi_amount) + '@0')
assert_raises_rpc_error(-8, 'Specified smart contract not found', self.nodes[1].executesmartcontract, 'DFIP9999', str(dfi_amount) + '@0')
assert_raises_rpc_error(-8, 'BTC source address must be provided for DFIP2201', self.nodes[1].executesmartcontract, dfip, str(btc_amount) + '@2')
assert_raises_rpc_error(-8, 'Specified smart contract not found', self.nodes[0].executesmartcontract, 'DFIP9999', str(dfi_amount) + '@0')
assert_raises_rpc_error(-8, 'BTC source address must be provided for DFIP2201', self.nodes[0].executesmartcontract, dfip, str(btc_amount) + '@2')

# Create tokens
self.nodes[0].createtoken({
Expand All @@ -59,48 +54,43 @@ def run_test(self):
self.nodes[0].generate(1)

# Create and fund address with BTC
address = self.nodes[1].getnewaddress("", "legacy")
address = self.nodes[0].getnewaddress("", "legacy")
self.nodes[0].minttokens("100000@BTC")
self.nodes[0].generate(1)
self.nodes[0].accounttoaccount(self.nodes[0].get_genesis_keys().ownerAuthAddress, {address: "20000@BTC"})
self.nodes[0].generate(1)
for _ in range(20):
self.nodes[0].sendtoaddress(address, 0.1)
self.nodes[0].generate(1)
self.sync_blocks()

# Check invalid calls
assert_raises_rpc_error(-32600, 'called before FortCanningHill height', self.nodes[1].executesmartcontract, dfip, str(btc_amount) + '@2', address)
assert_raises_rpc_error(-32600, 'called before FortCanningHill height', self.nodes[0].executesmartcontract, dfip, str(btc_amount) + '@2', address)

# Move to FortCanningHill
self.nodes[0].generate(1010 - self.nodes[0].getblockcount())
self.sync_blocks()

# Check invalid call
assert_raises_rpc_error(-32600, 'DFIP2201 smart contract is not enabled', self.nodes[1].executesmartcontract, dfip, str(btc_amount) + '@2', address)
assert_raises_rpc_error(-32600, 'DFIP2201 smart contract is not enabled', self.nodes[0].executesmartcontract, dfip, str(btc_amount) + '@2', address)

self.nodes[0].setgov({"ATTRIBUTES":{'v0/params/dfip2201/active':'false'}})
self.nodes[0].generate(1)

# Check invalid call
assert_raises_rpc_error(-32600, 'DFIP2201 smart contract is not enabled', self.nodes[1].executesmartcontract, dfip, str(btc_amount) + '@2', address)
assert_raises_rpc_error(-32600, 'DFIP2201 smart contract is not enabled', self.nodes[0].executesmartcontract, dfip, str(btc_amount) + '@2', address)

self.nodes[0].setgov({"ATTRIBUTES":{'v0/params/dfip2201/active':'true'}})
self.nodes[0].generate(1)

# Check invalid calls
assert_raises_rpc_error(-32600, 'is less than', self.nodes[1].executesmartcontract, dfip, '20000.00000001@2', address)
assert_raises_rpc_error(-3, 'Amount out of range', self.nodes[1].executesmartcontract, dfip, '0@2', address)
assert_raises_rpc_error(-32600, 'Specified token not found', self.nodes[1].executesmartcontract, dfip, str(btc_amount) + '@9999', address)
assert_raises_rpc_error(-32600, 'Only Bitcoin can be swapped in DFIP2201', self.nodes[1].executesmartcontract, dfip, str(btc_amount) + '@1', address)
assert_raises_rpc_error(-32600, 'fixedIntervalPrice with id <BTC/USD> not found', self.nodes[1].executesmartcontract, dfip, str(btc_amount) + '@2', address)
assert_raises_rpc_error(-32600, 'is less than', self.nodes[0].executesmartcontract, dfip, '20000.00000001@2', address)
assert_raises_rpc_error(-3, 'Amount out of range', self.nodes[0].executesmartcontract, dfip, '0@2', address)
assert_raises_rpc_error(-32600, 'Specified token not found', self.nodes[0].executesmartcontract, dfip, str(btc_amount) + '@9999', address)
assert_raises_rpc_error(-32600, 'Only Bitcoin can be swapped in DFIP2201', self.nodes[0].executesmartcontract, dfip, str(btc_amount) + '@1', address)
assert_raises_rpc_error(-32600, 'fixedIntervalPrice with id <BTC/USD> not found', self.nodes[0].executesmartcontract, dfip, str(btc_amount) + '@2', address)

# Test min swap
self.nodes[0].setgov({"ATTRIBUTES":{'v0/params/dfip2201/minswap':'0.00001'}})
self.nodes[0].generate(1)

# Check invalid calls
assert_raises_rpc_error(-32600, 'Below minimum swapable amount, must be at least 0.00001000 BTC', self.nodes[1].executesmartcontract, dfip, '0.00000999@2', address)
assert_raises_rpc_error(-32600, 'Below minimum swapable amount, must be at least 0.00001000 BTC', self.nodes[0].executesmartcontract, dfip, '0.00000999@2', address)

# Set up oracles
oracle_address = self.nodes[0].getnewaddress("", "legacy")
Expand All @@ -125,14 +115,13 @@ def run_test(self):
'fixedIntervalPriceId': "BTC/USD"})

self.nodes[0].generate(7)
self.sync_blocks()

# Import community balance
self.nodes[1].importprivkey('cMv1JaaZ9Mbb3M3oNmcFvko8p7EcHJ8XD7RCQjzNaMs7BWRVZTyR')
balance = self.nodes[1].getbalance()
self.nodes[0].importprivkey('cMv1JaaZ9Mbb3M3oNmcFvko8p7EcHJ8XD7RCQjzNaMs7BWRVZTyR')
balance = self.nodes[0].getbalance()

# Try and fund more than is in community balance
assert_raises_rpc_error(-4, 'Insufficient funds', self.nodes[1].executesmartcontract, dfip, '18336.22505381@0', address)
assert_raises_rpc_error(-4, 'Insufficient funds', self.nodes[0].executesmartcontract, dfip, '18336.22505381@0', address)

# Check smart contract details and balance
result = self.nodes[0].listsmartcontracts()
Expand All @@ -142,31 +131,30 @@ def run_test(self):
assert('0' not in result[0])

# Fund smart contract
tx = self.nodes[1].executesmartcontract(dfip, '18336.225@0')
self.nodes[1].generate(1)
self.sync_blocks()
tx = self.nodes[0].executesmartcontract(dfip, '18336.225@0')
self.nodes[0].generate(1)

# Check smart contract details and balance
result = self.nodes[0].listsmartcontracts()
assert_equal(result[0]['0'], Decimal('18336.225'))

# Check balance has changed as expected
block = self.nodes[0].getblock(self.nodes[0].getblockhash(self.nodes[0].getblockcount() - 100))
community_reward = self.nodes[0].getrawtransaction(block['tx'][0], 1)['vout'][1]['value']
fee = self.nodes[1].gettransaction(tx)['fee']
assert_equal(balance + community_reward - Decimal('18336.225') + fee, self.nodes[1].getbalance())
rewards = self.nodes[0].getrawtransaction(block['tx'][0], 1)['vout']
staker_reward = rewards[0]['value']
community_reward = rewards[1]['value']
fee = self.nodes[0].gettransaction(tx)['fee']
assert_equal(balance + staker_reward + community_reward - Decimal('18336.225') + fee, self.nodes[0].getbalance())

# Test swap for more than in community fund by 1 Sat
block = self.nodes[0].getblockcount() + 1
self.nodes[0].setgov({"ATTRIBUTES":{'v0/params/dfip2201/premium':'0.00000000'}})
self.nodes[0].generate(1)
self.sync_blocks()
assert_raises_rpc_error(-32600, 'amount 18336.22500000 is less than 18336.22500001', self.nodes[1].executesmartcontract, dfip, '18336.22500001@2', address)
assert_raises_rpc_error(-32600, 'amount 18336.22500000 is less than 18336.22500001', self.nodes[0].executesmartcontract, dfip, '18336.22500001@2', address)

# Test again for full amount in community balance
self.nodes[1].executesmartcontract(dfip, '18336.22500000@2', address)
self.nodes[1].generate(1)
self.sync_blocks()
self.nodes[0].executesmartcontract(dfip, '18336.22500000@2', address)
self.nodes[0].generate(1)
assert_equal(18336.22500000, float(self.nodes[0].getaccount(address)[0].split('@')[0]))
assert('0' not in self.nodes[0].listsmartcontracts())

Expand All @@ -179,80 +167,68 @@ def run_test(self):

# Test default 2.5% premium
block = self.nodes[0].getblockcount() + 1
self.nodes[1].executesmartcontract(dfip, '0.09999999@2', address)
self.nodes[1].generate(1)
self.sync_blocks()
self.nodes[0].executesmartcontract(dfip, '0.09999999@2', address)
self.nodes[0].generate(1)
assert_equal(2049.999795, float(self.nodes[0].getaccount(address)[0].split('@')[0]))

# Test 5% premium
self.rollback(block)
self.nodes[0].setgov({"ATTRIBUTES":{'v0/params/dfip2201/premium':'0.05'}})
self.nodes[0].generate(1)
self.sync_blocks()
self.nodes[1].executesmartcontract(dfip, '0.09999999@2', address)
self.nodes[1].generate(1)
self.sync_blocks()
self.nodes[0].executesmartcontract(dfip, '0.09999999@2', address)
self.nodes[0].generate(1)
assert_equal(2099.99979, float(self.nodes[0].getaccount(address)[0].split('@')[0]))

# Test 0.1% premium
self.rollback(block)
self.nodes[0].setgov({"ATTRIBUTES":{'v0/params/dfip2201/premium':'0.001'}})
self.nodes[0].generate(1)
self.sync_blocks()
self.nodes[1].executesmartcontract(dfip, '0.09999999@2', address)
self.nodes[1].generate(1)
self.sync_blocks()
self.nodes[0].executesmartcontract(dfip, '0.09999999@2', address)
self.nodes[0].generate(1)
assert_equal(2001.9997998, float(self.nodes[0].getaccount(address)[0].split('@')[0]))

# Test 0.000001% premium
self.rollback(block)
self.nodes[0].setgov({"ATTRIBUTES":{'v0/params/dfip2201/premium':'0.00000001'}})
self.nodes[0].generate(1)
self.sync_blocks()
self.nodes[1].executesmartcontract(dfip, '0.1@2', address)
self.nodes[1].generate(1)
self.sync_blocks()
self.nodes[0].executesmartcontract(dfip, '0.1@2', address)
self.nodes[0].generate(1)
assert_equal(2000.00002, float(self.nodes[0].getaccount(address)[0].split('@')[0]))

# Test 0% premium
self.rollback(block)
self.nodes[0].setgov({"ATTRIBUTES":{'v0/params/dfip2201/premium':'0.00000000'}})
self.nodes[0].generate(1)
self.sync_blocks()
self.nodes[1].executesmartcontract(dfip, '0.1@2', address)
self.nodes[1].generate(1)
self.sync_blocks()
self.nodes[0].executesmartcontract(dfip, '0.1@2', address)
self.nodes[0].generate(1)
assert_equal(2000, float(self.nodes[0].getaccount(address)[0].split('@')[0]))

# Swap min amount
self.rollback(block)
self.nodes[1].executesmartcontract(dfip, '0.00001@2', address)
self.nodes[1].generate(1)
self.sync_blocks()
self.nodes[0].executesmartcontract(dfip, '0.00001@2', address)
self.nodes[0].generate(1)
assert_equal(0.205, float(self.nodes[0].getaccount(address)[0].split('@')[0]))

# Test smallest min amount
self.rollback(block)
self.nodes[0].setgov({"ATTRIBUTES":{'v0/params/dfip2201/minswap':'0.00000001'}})
self.nodes[0].generate(1)
self.nodes[1].executesmartcontract(dfip, '0.00000001@2', address)
self.nodes[1].generate(1)
self.sync_blocks()
self.nodes[0].executesmartcontract(dfip, '0.00000001@2', address)
self.nodes[0].generate(1)
assert_equal(0.000205, float(self.nodes[0].getaccount(address)[0].split('@')[0]))

# Test no smallest min amount
self.rollback(block)
self.nodes[0].setgov({"ATTRIBUTES":{'v0/params/dfip2201/minswap':'0.00000001'}})
self.nodes[0].generate(1)
self.nodes[1].executesmartcontract(dfip, '0.00000001@2', address)
self.nodes[1].generate(1)
self.sync_blocks()
self.nodes[0].executesmartcontract(dfip, '0.00000001@2', address)
self.nodes[0].generate(1)
assert_equal(0.000205, float(self.nodes[0].getaccount(address)[0].split('@')[0]))

# Test disabling DFIP201
self.nodes[0].setgov({"ATTRIBUTES":{'v0/params/dfip2201/active':'false'}})
self.nodes[0].generate(1)
assert_raises_rpc_error(-32600, 'DFIP2201 smart contract is not enabled', self.nodes[1].executesmartcontract, dfip, '1@2', address)
assert_raises_rpc_error(-32600, 'DFIP2201 smart contract is not enabled', self.nodes[0].executesmartcontract, dfip, '1@2', address)

if __name__ == '__main__':
SmartContractTest().main()
Expand Down