diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 9a7fdc8bd..035262d5a 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -24,7 +24,6 @@ detect_stray_source_files("${sources}" ".")
set(contracts_sources
contracts/AuctionRegistrar.cpp
contracts/ContractInterface.h
- contracts/FixedFeeRegistrar.cpp
contracts/Wallet.cpp
)
detect_stray_source_files("${contracts_sources}" "contracts/")
diff --git a/test/contracts/FixedFeeRegistrar.cpp b/test/contracts/FixedFeeRegistrar.cpp
deleted file mode 100644
index b0f2ba8f6..000000000
--- a/test/contracts/FixedFeeRegistrar.cpp
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- This file is part of solidity.
-
- solidity is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- solidity is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with solidity. If not, see .
-*/
-// SPDX-License-Identifier: GPL-3.0
-/**
- * @author Christian
- * @date 2015
- * Tests for a fixed fee registrar contract.
- */
-
-#include
-
-#include
-#include
-#include
-
-#if defined(_MSC_VER)
-#pragma warning(push)
-#pragma warning(disable:4535) // calling _set_se_translator requires /EHa
-#endif
-#include
-#if defined(_MSC_VER)
-#pragma warning(pop)
-#endif
-
-#include
-
-using namespace std;
-using namespace solidity;
-using namespace solidity::util;
-using namespace solidity::test;
-
-namespace solidity::frontend::test
-{
-
-namespace
-{
-
-static char const* registrarCode = R"DELIMITER(
-//sol FixedFeeRegistrar
-// Simple global registrar with fixed-fee reservations.
-// @authors:
-// Gav Wood
-
-pragma solidity >=0.4.0 <0.9.0;
-
-abstract contract Registrar {
- event Changed(string indexed name);
-
- function owner(string memory _name) public virtual view returns (address o_owner);
- function addr(string memory _name) public virtual view returns (address o_address);
- function subRegistrar(string memory _name) virtual public view returns (address o_subRegistrar);
- function content(string memory _name) public virtual view returns (bytes32 o_content);
-}
-
-contract FixedFeeRegistrar is Registrar {
- struct Record {
- address addr;
- address subRegistrar;
- bytes32 content;
- address owner;
- }
-
- modifier onlyrecordowner(string memory _name) { if (m_record(_name).owner == msg.sender) _; }
-
- function reserve(string memory _name) public payable {
- Record storage rec = m_record(_name);
- if (rec.owner == 0x0000000000000000000000000000000000000000 && msg.value >= c_fee) {
- rec.owner = msg.sender;
- emit Changed(_name);
- }
- }
- function disown(string memory _name, address payable _refund) onlyrecordowner(_name) public {
- delete m_recordData[uint(keccak256(bytes(_name))) / 8];
- if (!_refund.send(c_fee))
- revert();
- emit Changed(_name);
- }
- function transfer(string memory _name, address _newOwner) onlyrecordowner(_name) public {
- m_record(_name).owner = _newOwner;
- emit Changed(_name);
- }
- function setAddr(string memory _name, address _a) onlyrecordowner(_name) public {
- m_record(_name).addr = _a;
- emit Changed(_name);
- }
- function setSubRegistrar(string memory _name, address _registrar) onlyrecordowner(_name) public {
- m_record(_name).subRegistrar = _registrar;
- emit Changed(_name);
- }
- function setContent(string memory _name, bytes32 _content) onlyrecordowner(_name) public {
- m_record(_name).content = _content;
- emit Changed(_name);
- }
-
- function record(string memory _name) public view returns (address o_addr, address o_subRegistrar, bytes32 o_content, address o_owner) {
- Record storage rec = m_record(_name);
- o_addr = rec.addr;
- o_subRegistrar = rec.subRegistrar;
- o_content = rec.content;
- o_owner = rec.owner;
- }
- function addr(string memory _name) public override view returns (address) { return m_record(_name).addr; }
- function subRegistrar(string memory _name) public override view returns (address) { return m_record(_name).subRegistrar; }
- function content(string memory _name) public override view returns (bytes32) { return m_record(_name).content; }
- function owner(string memory _name) public override view returns (address) { return m_record(_name).owner; }
-
- Record[2**253] m_recordData;
- function m_record(string memory _name) view internal returns (Record storage o_record) {
- return m_recordData[uint(keccak256(bytes(_name))) / 8];
- }
- uint constant c_fee = 69 ether;
-}
-)DELIMITER";
-
-static LazyInit s_compiledRegistrar;
-
-class RegistrarTestFramework: public SolidityExecutionFramework
-{
-protected:
- void deployRegistrar()
- {
- bytes const& compiled = s_compiledRegistrar.init([&]{
- return compileContract(registrarCode, "FixedFeeRegistrar");
- });
-
- sendMessage(compiled, true);
- BOOST_REQUIRE(m_transactionSuccessful);
- BOOST_REQUIRE(!m_output.empty());
- }
- u256 const m_fee = u256("69000000000000000000");
-};
-
-}
-
-/// This is a test suite that tests optimised code!
-BOOST_FIXTURE_TEST_SUITE(SolidityFixedFeeRegistrar, RegistrarTestFramework)
-
-BOOST_AUTO_TEST_CASE(creation)
-{
- deployRegistrar();
-}
-
-BOOST_AUTO_TEST_CASE(reserve)
-{
- // Test that reserving works and fee is taken into account.
- deployRegistrar();
- string name[] = {"abc", "def", "ghi"};
- BOOST_REQUIRE(callContractFunctionWithValue("reserve(string)", m_fee, encodeDyn(name[0])) == encodeArgs());
- BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name[0])) == encodeArgs(account(0)));
- BOOST_REQUIRE(callContractFunctionWithValue("reserve(string)", m_fee + 1, encodeDyn(name[1])) == encodeArgs());
- BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name[1])) == encodeArgs(account(0)));
- BOOST_REQUIRE(callContractFunctionWithValue("reserve(string)", m_fee - 1, encodeDyn(name[2])) == encodeArgs());
- BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name[2])) == encodeArgs(h160{}));
-}
-
-BOOST_AUTO_TEST_CASE(double_reserve)
-{
- // Test that it is not possible to re-reserve from a different address.
- deployRegistrar();
- string name = "abc";
- BOOST_REQUIRE(callContractFunctionWithValue("reserve(string)", m_fee, encodeDyn(name)) == encodeArgs());
- BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name)) == encodeArgs(account(0)));
-
- sendEther(account(1), 100 * ether);
- m_sender = account(1);
- BOOST_REQUIRE(callContractFunctionWithValue("reserve(string)", m_fee, encodeDyn(name)) == encodeArgs());
- BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name)) == encodeArgs(account(0)));
-}
-
-BOOST_AUTO_TEST_CASE(properties)
-{
- // Test setting and retrieving the various properties works.
- deployRegistrar();
- string names[] = {"abc", "def", "ghi"};
- size_t addr = 0x9872543;
- size_t count = 1;
- for (string const& name: names)
- {
- addr++;
- m_sender = account(0);
- sendEther(account(count), 100 * ether);
- m_sender = account(count);
- h160 owner = m_sender;
- // setting by sender works
- BOOST_REQUIRE(callContractFunctionWithValue("reserve(string)", m_fee, encodeDyn(name)) == encodeArgs());
- BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name)) == encodeArgs(owner));
- BOOST_CHECK(callContractFunction("setAddr(string,address)", u256(0x40), u256(addr), u256(name.length()), name) == encodeArgs());
- BOOST_CHECK(callContractFunction("addr(string)", encodeDyn(name)) == encodeArgs(addr));
- BOOST_CHECK(callContractFunction("setSubRegistrar(string,address)", u256(0x40), addr + 20, u256(name.length()), name) == encodeArgs());
- BOOST_CHECK(callContractFunction("subRegistrar(string)", encodeDyn(name)) == encodeArgs(addr + 20));
- BOOST_CHECK(callContractFunction("setContent(string,bytes32)", u256(0x40), addr + 90, u256(name.length()), name) == encodeArgs());
- BOOST_CHECK(callContractFunction("content(string)", encodeDyn(name)) == encodeArgs(addr + 90));
- count++;
- // but not by someone else
- m_sender = account(0);
- sendEther(account(count), 100 * ether);
- m_sender = account(count);
- BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name)) == encodeArgs(owner));
- BOOST_CHECK(callContractFunction("setAddr(string,address)", u256(0x40), addr + 1, u256(name.length()), name) == encodeArgs());
- BOOST_CHECK(callContractFunction("addr(string)", encodeDyn(name)) == encodeArgs(addr));
- BOOST_CHECK(callContractFunction("setSubRegistrar(string,address)", u256(0x40), addr + 20 + 1, u256(name.length()), name) == encodeArgs());
- BOOST_CHECK(callContractFunction("subRegistrar(string)", encodeDyn(name)) == encodeArgs(addr + 20));
- BOOST_CHECK(callContractFunction("setContent(string,bytes32)", u256(0x40), addr + 90 + 1, u256(name.length()), name) == encodeArgs());
- BOOST_CHECK(callContractFunction("content(string)", encodeDyn(name)) == encodeArgs(addr + 90));
- count++;
- }
-}
-
-BOOST_AUTO_TEST_CASE(transfer)
-{
- deployRegistrar();
- string name = "abc";
- BOOST_REQUIRE(callContractFunctionWithValue("reserve(string)", m_fee, encodeDyn(name)) == encodeArgs());
- BOOST_CHECK(callContractFunction("setContent(string,bytes32)", u256(0x40), account(0), u256(name.length()), name) == encodeArgs());
- BOOST_CHECK(callContractFunction("transfer(string,address)", u256(0x40), u256(555), u256(name.length()), name) == encodeArgs());
- BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name)) == encodeArgs(u256(555)));
- BOOST_CHECK(callContractFunction("content(string)", encodeDyn(name)) == encodeArgs(account(0)));
-}
-
-BOOST_AUTO_TEST_CASE(disown)
-{
- deployRegistrar();
- string name = "abc";
- BOOST_REQUIRE(callContractFunctionWithValue("reserve(string)", m_fee, encodeDyn(name)) == encodeArgs());
- BOOST_CHECK(callContractFunction("setContent(string,bytes32)", u256(0x40), account(0), u256(name.length()), name) == encodeArgs());
- BOOST_CHECK(callContractFunction("setAddr(string,address)", u256(0x40), u256(124), u256(name.length()), name) == encodeArgs());
- BOOST_CHECK(callContractFunction("setSubRegistrar(string,address)", u256(0x40), u256(125), u256(name.length()), name) == encodeArgs());
-
- BOOST_CHECK_EQUAL(balanceAt(h160(0x124)), 0);
- BOOST_CHECK(callContractFunction("disown(string,address)", u256(0x40), u256(0x124), name.size(), name) == encodeArgs());
- BOOST_CHECK_EQUAL(balanceAt(h160(0x124)), m_fee);
-
- BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name)) == encodeArgs(u256(0)));
- BOOST_CHECK(callContractFunction("content(string)", encodeDyn(name)) == encodeArgs(u256(0)));
- BOOST_CHECK(callContractFunction("addr(string)", encodeDyn(name)) == encodeArgs(u256(0)));
- BOOST_CHECK(callContractFunction("subRegistrar(string)", encodeDyn(name)) == encodeArgs(u256(0)));
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-
-} // end namespaces
diff --git a/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol b/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol
new file mode 100644
index 000000000..b6d8f4399
--- /dev/null
+++ b/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol
@@ -0,0 +1,111 @@
+//sol FixedFeeRegistrar
+// Simple global registrar with fixed-fee reservations.
+// @authors:
+// Gav Wood
+
+pragma solidity >=0.4.0 <0.9.0;
+
+abstract contract Registrar {
+ event Changed(string indexed name);
+
+ function owner(string memory _name) public virtual view returns (address o_owner);
+ function addr(string memory _name) public virtual view returns (address o_address);
+ function subRegistrar(string memory _name) virtual public view returns (address o_subRegistrar);
+ function content(string memory _name) public virtual view returns (bytes32 o_content);
+}
+
+contract FixedFeeRegistrar is Registrar {
+ struct Record {
+ address addr;
+ address subRegistrar;
+ bytes32 content;
+ address owner;
+ }
+
+ modifier onlyrecordowner(string memory _name) { if (m_record(_name).owner == msg.sender) _; }
+
+ function reserve(string memory _name) public payable {
+ Record storage rec = m_record(_name);
+ if (rec.owner == 0x0000000000000000000000000000000000000000 && msg.value >= c_fee) {
+ rec.owner = msg.sender;
+ emit Changed(_name);
+ }
+ }
+ function disown(string memory _name, address payable _refund) onlyrecordowner(_name) public {
+ delete m_recordData[uint(keccak256(bytes(_name))) / 8];
+ if (!_refund.send(c_fee))
+ revert();
+ emit Changed(_name);
+ }
+ function transfer(string memory _name, address _newOwner) onlyrecordowner(_name) public {
+ m_record(_name).owner = _newOwner;
+ emit Changed(_name);
+ }
+ function setAddr(string memory _name, address _a) onlyrecordowner(_name) public {
+ m_record(_name).addr = _a;
+ emit Changed(_name);
+ }
+ function setSubRegistrar(string memory _name, address _registrar) onlyrecordowner(_name) public {
+ m_record(_name).subRegistrar = _registrar;
+ emit Changed(_name);
+ }
+ function setContent(string memory _name, bytes32 _content) onlyrecordowner(_name) public {
+ m_record(_name).content = _content;
+ emit Changed(_name);
+ }
+
+ function record(string memory _name) public view returns (address o_addr, address o_subRegistrar, bytes32 o_content, address o_owner) {
+ Record storage rec = m_record(_name);
+ o_addr = rec.addr;
+ o_subRegistrar = rec.subRegistrar;
+ o_content = rec.content;
+ o_owner = rec.owner;
+ }
+ function addr(string memory _name) public override view returns (address) { return m_record(_name).addr; }
+ function subRegistrar(string memory _name) public override view returns (address) { return m_record(_name).subRegistrar; }
+ function content(string memory _name) public override view returns (bytes32) { return m_record(_name).content; }
+ function owner(string memory _name) public override view returns (address) { return m_record(_name).owner; }
+
+ Record[2**253] m_recordData;
+ function m_record(string memory _name) view internal returns (Record storage o_record) {
+ return m_recordData[uint(keccak256(bytes(_name))) / 8];
+ }
+ uint constant c_fee = 69 ether;
+}
+// ====
+// compileViaYul: also
+// ----
+// constructor()
+// gas irOptimized: 544916
+// gas legacy: 942808
+// gas legacyOptimized: 492291
+// reserve(string), 69 ether: 0x20, 3, "abc" ->
+// gas irOptimized: 45527
+// gas legacy: 46242
+// gas legacyOptimized: 45491
+// owner(string): 0x20, 3, "abc" -> 0x1212121212121212121212121212120000000012
+// reserve(string), 70 ether: 0x20, 3, "def" ->
+// owner(string): 0x20, 3, "def" -> 0x1212121212121212121212121212120000000012
+// reserve(string), 68 ether: 0x20, 3, "ghi" ->
+// owner(string): 0x20, 3, "ghi" -> 0
+// account: 1 -> 0x1212121212121212121212121212120000001012
+// reserve(string), 69 ether: 0x20, 3, "abc" ->
+// owner(string): 0x20, 3, "abc" -> 0x1212121212121212121212121212120000000012
+// account: 0 -> 0x1212121212121212121212121212120000000012
+// setContent(string,bytes32): 0x40, 0, 3, "abc" ->
+// transfer(string,address): 0x40, 555, 3, "abc" ->
+// owner(string): 0x20, 3, "abc" -> 555
+// content(string): 0x20, 3, "abc" -> 0x00
+// setContent(string,bytes32): 0x40, 333, 3, "def" ->
+// setAddr(string,address): 0x40, 124, 3, "def" ->
+// setSubRegistrar(string,address): 0x40, 125, 3, "def" ->
+// content(string): 0x20, 3, "def" -> 333
+// addr(string): 0x20, 3, "def" -> 124
+// subRegistrar(string): 0x20, 3, "def" -> 125
+// balance: 0x124 -> 0
+// disown(string,address): 0x40, 0x124, 3, "def" ->
+// balance: 0x124 -> 0
+// owner(string): 0x20, 3, "def" -> 0
+// content(string): 0x20, 3, "def" -> 0
+// addr(string): 0x20, 3, "def" -> 0
+// subRegistrar(string): 0x20, 3, "def" -> 0