Skip to content

Commit

Permalink
Use EIP1167 for urn
Browse files Browse the repository at this point in the history
  • Loading branch information
telome committed Dec 20, 2023
1 parent ecb993c commit a160553
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 6 deletions.
25 changes: 22 additions & 3 deletions src/LockstakeEngine.sol
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ contract LockstakeEngine is Multicall {
MkrNgtLike immutable public mkrNgt;
GemLike immutable public ngt;
uint256 immutable public mkrNgtRate;
address immutable public urnImplementation;

// --- events ---

Expand Down Expand Up @@ -150,6 +151,7 @@ contract LockstakeEngine is Multicall {
ngt.approve(address(mkrNgt), type(uint256).max);
gov.approve(address(mkrNgt), type(uint256).max);
mkrNgtRate = mkrNgt.rate();
urnImplementation = address(new LockstakeUrn(address(vat), stkGov_));

wards[msg.sender] = 1;
emit Rely(msg.sender);
Expand All @@ -167,6 +169,16 @@ contract LockstakeEngine is Multicall {
ok = urnOwners[urn] == usr || urnCan[urn][usr] == 1;
}

// See the reference implementation in https://eips.ethereum.org/EIPS/eip-1167
function _initCode(bytes20 _target) internal pure returns (bytes memory code) {
code = new bytes(55);
assembly {
mstore(add(code, 0x20), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(code, add(0x20,0x14)), _target)
mstore(add(code, add(0x20,0x28)), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
}
}

// --- administration ---

function rely(address usr) external auth {
Expand Down Expand Up @@ -200,7 +212,7 @@ contract LockstakeEngine is Multicall {

function getUrn(address owner, uint256 index) external view returns (address urn) {
uint256 salt = uint256(keccak256(abi.encode(owner, index)));
bytes32 codeHash = keccak256(abi.encodePacked(type(LockstakeUrn).creationCode, abi.encode(vat, stkGov)));
bytes32 codeHash = keccak256(abi.encodePacked(_initCode(bytes20(urnImplementation))));
urn = address(uint160(uint256(
keccak256(
abi.encodePacked(bytes1(0xff), address(this), salt, codeHash)
Expand All @@ -215,8 +227,15 @@ contract LockstakeEngine is Multicall {

function open(uint256 index) external returns (address urn) {
require(index == usrAmts[msg.sender]++, "LockstakeEngine/urn-already-opened");
bytes32 salt = keccak256(abi.encode(msg.sender, index));
urn = address(new LockstakeUrn{salt: salt}(address(vat), address(stkGov)));

uint256 salt = uint256(keccak256(abi.encode(msg.sender, index)));
bytes memory initCode = _initCode(bytes20(urnImplementation));
assembly {
urn := create2(0, add(initCode, 0x20), mload(initCode), salt)
if iszero(extcodesize(urn)) { revert(0, 0) }
}
LockstakeUrn(urn).init();

urnOwners[urn] = msg.sender;
emit Open(msg.sender, urn);
}
Expand Down
9 changes: 7 additions & 2 deletions src/LockstakeUrn.sol
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ contract LockstakeUrn {

address immutable public engine;
GemLike immutable public stkGov;
VatLike immutable public vat;

// --- modifiers ---

Expand All @@ -46,12 +47,16 @@ contract LockstakeUrn {
_;
}

// --- constructor ---
// --- constructor & init ---

constructor(address vat_, address stkGov_) {
engine = msg.sender;
vat = VatLike(vat_);
stkGov = GemLike(stkGov_);
VatLike(vat_).hope(msg.sender);
}

function init() external isEngine {
vat.hope(msg.sender);
stkGov.approve(msg.sender, type(uint256).max);
}

Expand Down
2 changes: 1 addition & 1 deletion test/LockstakeEngine.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ interface CalcLike {
function file(bytes32, uint256) external;
}

contract AllocatorVaultTest is DssTest {
contract LockstakeEngineTest is DssTest {
using stdStorage for StdStorage;

address public pauseProxy;
Expand Down

0 comments on commit a160553

Please sign in to comment.