Skip to content

Instantly share code, notes, and snippets.

@botdad
Created December 22, 2021 19:14
Show Gist options
  • Save botdad/2e5af7d264ede5dfa4e12c7ba23f8e7d to your computer and use it in GitHub Desktop.
Save botdad/2e5af7d264ede5dfa4e12c7ba23f8e7d to your computer and use it in GitHub Desktop.
Proof of concept for rewritable data contracts
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.11;
import "./utils/Bytecode.sol";
contract CREATE07Proxy {
error ErrorDestroyingContract();
error ErrorDeployingToDeterministicAddress();
function deployDataContract(bytes memory data) external {
address nonce1Address = addressOf(1);
address nonce2Address = addressOf(2);
address dataContract;
bytes memory creationCode = Bytecode.creationCodeFor(
abi.encodePacked(
hex"33_73",
address(this),
hex"14_60_1B_57_00_5B_32_FF",
data
)
);
if (nonce1Address.code.length == 0) {
// deploy data at nonce 1
assembly {
dataContract := create(0, add(creationCode, 32), mload(creationCode))
}
if (dataContract != nonce1Address)
revert ErrorDeployingToDeterministicAddress();
if (nonce2Address.code.length != 0) {
// selfdestruct data contract at nonce 2
(bool success, ) = nonce2Address.call("");
if (!success) revert ErrorDestroyingContract();
}
} else {
// deploy data at nonce 2
assembly {
dataContract := create(0, add(creationCode, 32), mload(creationCode))
}
if (dataContract != nonce2Address)
revert ErrorDeployingToDeterministicAddress();
// selfdestruct data contract at nonce 1
(bool success, ) = nonce1Address.call("");
if (!success) revert ErrorDestroyingContract();
// selfdestruct this proxy to reset nonce to 1
// the next data write will redeploy this proxy
selfdestruct(payable(tx.origin));
}
}
function addressOf(uint8 nonce) internal view returns (address) {
return
address(
uint160(
uint256(keccak256(abi.encodePacked(hex"d6_94", address(this), nonce)))
)
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment