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

In TransferDomain handle ExtractDestination failure #2117

Merged
merged 5 commits into from
Jun 26, 2023
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
8 changes: 4 additions & 4 deletions src/masternodes/errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -427,23 +427,23 @@ class DeFiErrors {
}

static Res TransferDomainETHSourceAddress() {
return Res::Err("Src address must not be an ETH address in case of \"DVM\" domain");
return Res::Err("Src address must be an ETH address in case of \"EVM\" domain");
}

static Res TransferDomainDFISourceAddress() {
return Res::Err("Src address must be an ETH address in case of \"EVM\" domain");
return Res::Err("Src address must be a legacy or Bech32 address in case of \"DVM\" domain");
}

static Res TransferDomainInvalidSourceDomain() {
return Res::Err("Invalid domain set for \"src\" argument");
}

static Res TransferDomainETHDestinationAddress() {
return Res::Err("Dst address must not be an ETH address in case of \"DVM\" domain");
return Res::Err("Dst address must be an ETH address in case of \"EVM\" domain");
}

static Res TransferDomainDVMDestinationAddress() {
return Res::Err("Dst address must be an ETH address in case of \"EVM\" domain");
return Res::Err("Dst address must be a legacy or Bech32 address in case of \"DVM\" domain");
}

static Res TransferDomainInvalidDestinationDomain() {
Expand Down
70 changes: 58 additions & 12 deletions src/masternodes/mn_checks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3975,6 +3975,28 @@ Res HasAuth(const CTransaction &tx, const CCoinsViewCache &coins, const CScript
return DeFiErrors::InvalidAuth();
}

enum class DomainTransferType : uint8_t {
DVM,
EVM,
};

static bool DomainTransferAllowedAddress(const CScript &address, DomainTransferType type) {
CTxDestination dest;
if (ExtractDestination(address, dest)) {
if (type == DomainTransferType::DVM) {
if (dest.index() == PKHashType || dest.index() == WitV0KeyHashType) {
return true;
}
} else if (type == DomainTransferType::EVM) {
if (dest.index() == WitV16KeyEthHashType) {
return true;
}
}
}

return false;
}

Res ValidateTransferDomain(const CTransaction &tx,
uint32_t height,
const CCoinsViewCache &coins,
Expand Down Expand Up @@ -4009,9 +4031,15 @@ Res ValidateTransferDomain(const CTransaction &tx,
// Check domain type
if (src.domain == static_cast<uint8_t>(VMDomain::DVM)) {
// Reject if source address is ETH address
if (ExtractDestination(src.address, dest)) {
if (dest.index() == WitV16KeyEthHashType) {
return DeFiErrors::TransferDomainETHSourceAddress();
if (height < static_cast<uint32_t>(consensus.ChangiIntermediateHeight3)) {
if (ExtractDestination(src.address, dest)) {
if (dest.index() == WitV16KeyEthHashType) {
return DeFiErrors::TransferDomainDFISourceAddress();
}
}
} else {
if (!DomainTransferAllowedAddress(src.address, DomainTransferType::DVM)) {
return DeFiErrors::TransferDomainDFISourceAddress();
}
}
// Check for authorization on source address
Expand All @@ -4020,9 +4048,15 @@ Res ValidateTransferDomain(const CTransaction &tx,
return res;
} else if (src.domain == static_cast<uint8_t>(VMDomain::EVM)) {
// Reject if source address is DFI address
if (ExtractDestination(src.address, dest)) {
if (dest.index() != WitV16KeyEthHashType) {
return DeFiErrors::TransferDomainDFISourceAddress();
if (height < static_cast<uint32_t>(consensus.ChangiIntermediateHeight3)) {
if (ExtractDestination(src.address, dest)) {
if (dest.index() != WitV16KeyEthHashType) {
return DeFiErrors::TransferDomainETHSourceAddress();
}
}
} else {
if (!DomainTransferAllowedAddress(src.address, DomainTransferType::EVM)) {
return DeFiErrors::TransferDomainETHSourceAddress();
}
}
// Check for authorization on source address
Expand All @@ -4036,16 +4070,28 @@ Res ValidateTransferDomain(const CTransaction &tx,
// Check domain type
if (dst.domain == static_cast<uint8_t>(VMDomain::DVM)) {
// Reject if source address is ETH address
if (ExtractDestination(dst.address, dest)) {
if (dest.index() == WitV16KeyEthHashType) {
return DeFiErrors::TransferDomainETHDestinationAddress();
if (height < static_cast<uint32_t>(consensus.ChangiIntermediateHeight3)) {
if (ExtractDestination(dst.address, dest)) {
if (dest.index() == WitV16KeyEthHashType) {
return DeFiErrors::TransferDomainDVMDestinationAddress();
}
}
} else {
if (!DomainTransferAllowedAddress(dst.address, DomainTransferType::DVM)) {
return DeFiErrors::TransferDomainDVMDestinationAddress();
}
}
} else if (dst.domain == static_cast<uint8_t>(VMDomain::EVM)) {
// Reject if source address is DFI address
if (ExtractDestination(dst.address, dest)) {
if (dest.index() != WitV16KeyEthHashType) {
return DeFiErrors::TransferDomainDVMDestinationAddress();
if (height < static_cast<uint32_t>(consensus.ChangiIntermediateHeight3)) {
if (ExtractDestination(dst.address, dest)) {
if (dest.index() != WitV16KeyEthHashType) {
return DeFiErrors::TransferDomainETHDestinationAddress();
}
}
} else {
if (!DomainTransferAllowedAddress(dst.address, DomainTransferType::EVM)) {
return DeFiErrors::TransferDomainETHDestinationAddress();
}
}
} else
Expand Down
8 changes: 4 additions & 4 deletions test/functional/feature_evm.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ def set_test_params(self):
self.num_nodes = 2
self.setup_clean_chain = True
self.extra_args = [
['-dummypos=0', '-txnotokens=0', '-amkheight=50', '-bayfrontheight=51', '-eunosheight=80', '-fortcanningheight=82', '-fortcanninghillheight=84', '-fortcanningroadheight=86', '-fortcanningcrunchheight=88', '-fortcanningspringheight=90', '-fortcanninggreatworldheight=94', '-fortcanningepilogueheight=96', '-grandcentralheight=101', '-nextnetworkupgradeheight=105', '-changiintermediateheight=105', '-subsidytest=1', '-txindex=1'],
['-dummypos=0', '-txnotokens=0', '-amkheight=50', '-bayfrontheight=51', '-eunosheight=80', '-fortcanningheight=82', '-fortcanninghillheight=84', '-fortcanningroadheight=86', '-fortcanningcrunchheight=88', '-fortcanningspringheight=90', '-fortcanninggreatworldheight=94', '-fortcanningepilogueheight=96', '-grandcentralheight=101', '-nextnetworkupgradeheight=105', '-changiintermediateheight=105', '-subsidytest=1', '-txindex=1']
['-dummypos=0', '-txnotokens=0', '-amkheight=50', '-bayfrontheight=51', '-eunosheight=80', '-fortcanningheight=82', '-fortcanninghillheight=84', '-fortcanningroadheight=86', '-fortcanningcrunchheight=88', '-fortcanningspringheight=90', '-fortcanninggreatworldheight=94', '-fortcanningepilogueheight=96', '-grandcentralheight=101', '-nextnetworkupgradeheight=105', '-changiintermediateheight=105', '-changiintermediate3height=105', '-subsidytest=1', '-txindex=1'],
['-dummypos=0', '-txnotokens=0', '-amkheight=50', '-bayfrontheight=51', '-eunosheight=80', '-fortcanningheight=82', '-fortcanninghillheight=84', '-fortcanningroadheight=86', '-fortcanningcrunchheight=88', '-fortcanningspringheight=90', '-fortcanninggreatworldheight=94', '-fortcanningepilogueheight=96', '-grandcentralheight=101', '-nextnetworkupgradeheight=105', '-changiintermediateheight=105', '-changiintermediate3height=105', '-subsidytest=1', '-txindex=1']
]

def test_tx_without_chainid(self, node, keypair):
Expand Down Expand Up @@ -120,7 +120,7 @@ def run_test(self):
assert_raises_rpc_error(-5, "recipient (blablabla) does not refer to any valid address", self.nodes[0].transferdomain, [{"src": {"address":address, "amount":"100@DFI", "domain": 2}, "dst":{"address":"blablabla", "amount":"100@DFI", "domain": 3}}])

# Check for valid values DVM->EVM in transferdomain rpc
assert_raises_rpc_error(-32600, "Src address must not be an ETH address in case of \"DVM\" domain", self.nodes[0].transferdomain, [{"src": {"address":eth_address, "amount":"100@DFI", "domain": 2}, "dst":{"address":eth_address, "amount":"100@DFI", "domain": 3}}])
assert_raises_rpc_error(-32600, "Src address must be a legacy or Bech32 address in case of \"DVM\" domain", self.nodes[0].transferdomain, [{"src": {"address":eth_address, "amount":"100@DFI", "domain": 2}, "dst":{"address":eth_address, "amount":"100@DFI", "domain": 3}}])
assert_raises_rpc_error(-32600, "Dst address must be an ETH address in case of \"EVM\" domain", self.nodes[0].transferdomain, [{"src": {"address":address, "amount":"100@DFI", "domain": 2}, "dst":{"address":address, "amount":"100@DFI", "domain": 3}}])
assert_raises_rpc_error(-32600, "Cannot transfer inside same domain", self.nodes[0].transferdomain, [{"src": {"address":address, "amount":"100@DFI", "domain": 2}, "dst":{"address":eth_address, "amount":"100@DFI", "domain": 2}}])
assert_raises_rpc_error(-32600, "Source amount must be equal to destination amount", self.nodes[0].transferdomain, [{"src": {"address":address, "amount":"100@DFI", "domain": 2}, "dst":{"address":eth_address, "amount":"101@DFI", "domain": 3}}])
Expand Down Expand Up @@ -156,7 +156,7 @@ def run_test(self):

# Check for valid values EVM->DVM in transferdomain rpc
assert_raises_rpc_error(-32600, "Src address must be an ETH address in case of \"EVM\" domain", self.nodes[0].transferdomain, [{"src": {"address":address, "amount":"100@DFI", "domain": 3}, "dst":{"address":address, "amount":"100@DFI", "domain": 2}}])
assert_raises_rpc_error(-32600, "Dst address must not be an ETH address in case of \"DVM\" domain", self.nodes[0].transferdomain, [{"src": {"address":eth_address, "amount":"100@DFI", "domain": 3}, "dst":{"address":eth_address, "amount":"100@DFI", "domain": 2}}])
assert_raises_rpc_error(-32600, "Dst address must be a legacy or Bech32 address in case of \"DVM\" domain", self.nodes[0].transferdomain, [{"src": {"address":eth_address, "amount":"100@DFI", "domain": 3}, "dst":{"address":eth_address, "amount":"100@DFI", "domain": 2}}])
assert_raises_rpc_error(-32600, "Cannot transfer inside same domain", self.nodes[0].transferdomain, [{"src": {"address":eth_address, "amount":"100@DFI", "domain": 3}, "dst":{"address":address, "amount":"100@DFI", "domain": 3}}])
assert_raises_rpc_error(-32600, "Source amount must be equal to destination amount", self.nodes[0].transferdomain, [{"src": {"address":eth_address, "amount":"100@DFI", "domain": 3}, "dst":{"address":address, "amount":"101@DFI", "domain": 2}}])
assert_raises_rpc_error(-32600, "For transferdomain, only DFI token is currently supported", self.nodes[0].transferdomain, [{"src": {"address":eth_address, "amount":"100@BTC", "domain": 3}, "dst":{"address":address, "amount":"100@DFI", "domain": 2}}])
Expand Down