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

Deploy stuff #4

Merged
merged 3 commits into from
Dec 28, 2022
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
cache/
out/
broadcast/
47 changes: 47 additions & 0 deletions script/Curta.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

import "forge-std/Script.sol";
import "forge-std/Test.sol";

import "../src/BaseRenderer.sol";
import "../src/Curta.sol";
import "../src/AuthorshipToken.sol";
import { LibRLP } from "../src/utils/LibRLP.sol";
import { ITokenRenderer } from "../src/interfaces/ITokenRenderer.sol";
import { IMinimalERC721 } from "../src/interfaces/IMinimalERC721.sol";

contract CurtaScript is Script {
function run() public returns (Curta curta) {
uint256 deployerPrivateKey = uint256(vm.envBytes32("PRIVATE_KEY"));
uint256 curtaKey = vm.envUint("CURTA_PRIVATE_KEY");

address curtaDeployerAddress = vm.addr(curtaKey);
address curtaAddress = LibRLP.computeAddress(curtaDeployerAddress, 0);

vm.startBroadcast(deployerPrivateKey);

// The renderer for Curta
ITokenRenderer tokenRenderer = new BaseRenderer();

// Give the Curta deployer some ETH.
payable(curtaDeployerAddress).transfer(0.25 ether);

// Deploy the authorship token.
IMinimalERC721 authorshipToken = new AuthorshipToken(curtaAddress, bytes32(uint256(0x01))); // TODO: give valid merkle root

vm.stopBroadcast();



// Deploy Curta using the Curta deployer.
vm.startBroadcast(curtaKey);

console.log("Predicted CURTA Address: ");
console.log(curtaAddress);

curta = new Curta(tokenRenderer, authorshipToken);

vm.stopBroadcast();
}
}
25 changes: 25 additions & 0 deletions script/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Notes to deploy Curta

## Setup

1. Set environment variables

- `PRIVATE_KEY`: The private key with enough funds to deploy all contracts necessary.

- `CURTA_PRIVATE_KEY`: Very important: must be a private key that has never deployed any contracts. We will use the public key of this wallet to compute the Curta contract address.

## Commands

### Anvil Testnet

`PRIVATE_KEY` should be set to the testnet default funded account with public key `0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266`.

```bash
forge script script/Curta.s.sol --rpc-url https://anviltestnet-test.up.railway.app/ --broadcast --sender 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266
```

### Constellation

```bash
forge script script/Curta.s.sol --rpc-url https://waterfall.constellationchain.xyz/http --broadcast --legacy --sender 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266
```
7 changes: 6 additions & 1 deletion src/AuthorshipToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
pragma solidity ^0.8.17;

import { ERC721 } from "solmate/tokens/ERC721.sol";
import { IMinimalERC721 } from "./interfaces/IMinimalERC721.sol";
import { MerkleProofLib } from "solmate/utils/MerkleProofLib.sol";

contract AuthorshipToken is ERC721 {
contract AuthorshipToken is IMinimalERC721, ERC721 {
// -------------------------------------------------------------------------
// Errors
// -------------------------------------------------------------------------
Expand Down Expand Up @@ -64,6 +65,10 @@ contract AuthorshipToken is ERC721 {
}
}

function ownerOf(uint256 _tokenId) public view override(ERC721, IMinimalERC721) returns (address) {
return ownerOf(_tokenId);
}

// -------------------------------------------------------------------------
// ERC721Metadata
// -------------------------------------------------------------------------
Expand Down
28 changes: 28 additions & 0 deletions src/utils/LibRLP.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// SPDX-License-Identifier: Unlicense
pragma solidity >=0.8.0;

import {Bytes32AddressLib} from "solmate/utils/Bytes32AddressLib.sol";

// prettier-ignore
library LibRLP {
using Bytes32AddressLib for bytes32;

function computeAddress(address deployer, uint256 nonce) public pure returns (address) {
// The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80, computed via 0x80 + 0.
// A one byte integer uses its own value as its length prefix, there is no additional "0x80 + length" prefix that comes before it.
if (nonce == 0x00) return keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80))).fromLast20Bytes();
if (nonce <= 0x7f) return keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce))).fromLast20Bytes();

// Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix of 0x80 + length.
if (nonce <= type(uint8).max) return keccak256(abi.encodePacked(bytes1(0xd7), bytes1(0x94), deployer, bytes1(0x81), uint8(nonce))).fromLast20Bytes();
if (nonce <= type(uint16).max) return keccak256(abi.encodePacked(bytes1(0xd8), bytes1(0x94), deployer, bytes1(0x82), uint16(nonce))).fromLast20Bytes();
if (nonce <= type(uint24).max) return keccak256(abi.encodePacked(bytes1(0xd9), bytes1(0x94), deployer, bytes1(0x83), uint24(nonce))).fromLast20Bytes();

// More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp
// 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce)
// 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex)
// 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex)
// We assume nobody can have a nonce large enough to require more than 32 bytes.
return keccak256(abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce))).fromLast20Bytes();
}
}