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
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:
dapp test output:
Both addresses: 0x99db7a7dcb7726ec5d29d08d50685dd8d8843915
Expected different addresses.
Eg remix:
Possibly useful summary of constructed contract addresses:
source
Possibly partially related: #40