Skip to content

Duplicate addresses for distinct newly created contracts. #70

@jzaki

Description

@jzaki

Inside test functions setup() or a test...(), it is possible for two contracts to be created with the same address. Specifically between a contract created in a constructor, and a contract created in a function.
Example:

contract AContract {}


contract Collection {
    event Addresses(address, string);

    constructor() public {
        emit Addresses(new AContract(), "new in constructor");
    }
    
    function createFunction() public {
        emit Addresses(new AContract(), "new in function");
    }
}


contract AddressbugTest is DSTest {

    function setUp() public {
        Collection collection = new Collection();
        collection.createFunction();
    }

    function testBasicSanity() public {
        assertTrue(false);
    }

}

dapp test output:

src/Addressbug.t.sol:AddressbugTest
   ├╴constructor
   ├╴initialize test
   │  ├╴create Collection (src/Addressbug.t.sol:27)
   │  │  ├╴create AContract (src/Addressbug.t.sol:15)
   │  │  └╴Addresses(0x99db7a7dcb7726ec5d29d08d50685dd8d8843915, "new in constructor") (src/Addressbug.t.sol:15)
   │  └╴call Collection::createFunction()() (src/Addressbug.t.sol:28)
   │     ├╴create AContract (src/Addressbug.t.sol:19)
   │     └╴Addresses(0x99db7a7dcb7726ec5d29d08d50685dd8d8843915, "new in function") (src/Addressbug.t.sol:19)
   └╴testBasicSanity()
      └╴log_bytes32("Assertion failed") (lib/ds-test/src/test.sol:56)

Both addresses: 0x99db7a7dcb7726ec5d29d08d50685dd8d8843915

Expected different addresses.
Eg remix:

[
	{
		"from": "0x9303a10f5aee3a50aff33807f78c0e7264be20b8",
		"topic": "0x1536377df3f3504a004885fa2e8057b751df91abe9e49f1d13ec79cc4e1193c1",
		"event": "Addresses",
		"args": {
			"0": "0x4c8bF2546Cdc9CBfd00a1121a7b2730b3e3249eC",
			"1": "new in constructor",
			"length": 2
		}
	},
	{
		"from": "0x9303a10f5aee3a50aff33807f78c0e7264be20b8",
		"topic": "0x1536377df3f3504a004885fa2e8057b751df91abe9e49f1d13ec79cc4e1193c1",
		"event": "Addresses",
		"args": {
			"0": "0x5B14f277cCdc89905e2a2A93d69A478722e58037",
			"1": "new in function",
			"length": 2
		}
	}
]

Possibly useful summary of constructed contract addresses:

The address for an Ethereum contract is deterministically computed from the address of its creator (sender) and how many transactions the creator has sent (nonce). The sender and nonce are RLP encoded and then hashed with Keccak-256.

source

Possibly partially related: #40

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions