Skip to content

Commit

Permalink
Allow urn management to another address
Browse files Browse the repository at this point in the history
  • Loading branch information
sunbreak1211 committed Dec 7, 2023
1 parent b69c955 commit 2deb688
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 19 deletions.
49 changes: 31 additions & 18 deletions src/LockstakeEngine.sol
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,14 @@ interface JugLike {
contract LockstakeEngine {
// --- storage variables ---

mapping(address => uint256) public wards; // usr => 1 == access
mapping(address => uint256) public farms; // farm => 1 == whitelisted
mapping(address => uint256) public usrAmts; // usr => urns amount
mapping(address => address) public urnOwners; // urn => owner
mapping(address => address) public urnDelegates; // urn => current associated delegate
mapping(address => address) public selectedFarm; // urn => current selected farm
JugLike public jug;
mapping(address => uint256) public wards; // usr => 1 == access
mapping(address => uint256) public farms; // farm => 1 == whitelisted
mapping(address => uint256) public usrAmts; // usr => urns amount
mapping(address => address) public urnOwners; // urn => owner
mapping(address => mapping(address => uint256)) public urnCan; // urn => usr => allowed (1 = yes, 0 = no)
mapping(address => address) public urnDelegates; // urn => current associated delegate
mapping(address => address) public selectedFarm; // urn => current selected farm
JugLike public jug;

// --- constants ---

Expand All @@ -90,6 +91,8 @@ contract LockstakeEngine {
event AddFarm(address farm);
event DelFarm(address farm);
event Open(address indexed owner, address urn);
event Hope(address indexed urn, address indexed usr);
event Nope(address indexed urn, address indexed usr);
event Delegate(address indexed urn, address indexed delegate);
event Lock(address indexed urn, uint256 wad);
event Free(address indexed urn, uint256 wad, uint256 burn);
Expand All @@ -111,8 +114,8 @@ contract LockstakeEngine {
_;
}

modifier urnOwner(address urn) {
require(urnOwners[urn] == msg.sender, "LockstakeEngine/not-urn-owner");
modifier urnAuth(address urn) {
require(urnOwners[urn] == msg.sender || urnCan[urn][msg.sender] == 1, "LockstakeEngine/urn-not-authorized");
_;
}

Expand Down Expand Up @@ -198,7 +201,17 @@ contract LockstakeEngine {
emit Open(msg.sender, urn);
}

function lock(address urn, uint256 wad) external urnOwner(urn) {
function hope(address urn, address usr) external urnAuth(urn) {
urnCan[urn][usr] = 1;
emit Hope(urn, usr);
}

function nope(address urn, address usr) external urnAuth(urn) {
urnCan[urn][usr] = 0;
emit Nope(urn, usr);
}

function lock(address urn, uint256 wad) external urnAuth(urn) {
require(wad <= uint256(type(int256).max), "LockstakeEngine/wad-overflow");
gov.transferFrom(msg.sender, address(this), wad);
address delegate_ = urnDelegates[urn];
Expand All @@ -214,7 +227,7 @@ contract LockstakeEngine {
emit Lock(urn, wad);
}

function free(address urn, uint256 wad) external urnOwner(urn) {
function free(address urn, uint256 wad) external urnAuth(urn) {
require(wad <= uint256(type(int256).max), "LockstakeEngine/wad-overflow");
vat.frob(ilk, urn, urn, address(0), -int256(wad), 0);
vat.slip(ilk, urn, -int256(wad));
Expand All @@ -229,7 +242,7 @@ contract LockstakeEngine {
emit Free(urn, wad, burn);
}

function delegate(address urn, address delegate_) external urnOwner(urn) {
function delegate(address urn, address delegate_) external urnAuth(urn) {
require(delegate_ == address(0) || delegateFactory.isDelegate(delegate_) == 1, "LockstakeEngine/not-valid-delegate");
address prevDelegate = urnDelegates[urn];
require(prevDelegate != delegate_, "LockstakeEngine/same-delegate");
Expand All @@ -249,7 +262,7 @@ contract LockstakeEngine {

// --- loan functions ---

function draw(address urn, uint256 wad) external urnOwner(urn) {
function draw(address urn, uint256 wad) external urnAuth(urn) {
uint256 rate = jug.drip(ilk);
uint256 dart = _divup(wad * RAY, rate);
require(dart <= uint256(type(int256).max), "LockstakeEngine/overflow");
Expand All @@ -258,7 +271,7 @@ contract LockstakeEngine {
emit Draw(urn, wad);
}

function wipe(address urn, uint256 wad) external urnOwner(urn) {
function wipe(address urn, uint256 wad) external urnAuth(urn) {
nst.transferFrom(msg.sender, address(this), wad);
nstJoin.join(address(this), wad);
uint256 rate = jug.drip(ilk);
Expand All @@ -270,29 +283,29 @@ contract LockstakeEngine {

// --- staking functions ---

function selectFarm(address urn, address farm) external urnOwner(urn) {
function selectFarm(address urn, address farm) external urnAuth(urn) {
require(farms[farm] == 1, "LockstakeEngine/non-existing-farm");
address selectedFarmUrn = selectedFarm[urn];
require(selectedFarmUrn == address(0) || GemLike(selectedFarmUrn).balanceOf(address(urn)) == 0, "LockstakeEngine/withdraw-first");
selectedFarm[urn] = farm;
emit SelectFarm(urn, farm);
}

function stake(address urn, uint256 wad, uint16 ref) external urnOwner(urn) {
function stake(address urn, uint256 wad, uint16 ref) external urnAuth(urn) {
address selectedFarmUrn = selectedFarm[urn];
require(selectedFarmUrn != address(0), "LockstakeEngine/missing-selected-farm");
LockstakeUrn(urn).stake(selectedFarmUrn, wad, ref);
emit Stake(urn, selectedFarmUrn, wad, ref);
}

function withdraw(address urn, uint256 amt) external urnOwner(urn) {
function withdraw(address urn, uint256 amt) external urnAuth(urn) {
address selectedFarmUrn = selectedFarm[urn];
require(selectedFarmUrn != address(0), "LockstakeEngine/missing-selected-farm");
LockstakeUrn(urn).withdraw(selectedFarmUrn, amt);
emit Withdraw(urn, selectedFarmUrn, amt);
}

function getReward(address urn, address farm) external urnOwner(urn) {
function getReward(address urn, address farm) external urnAuth(urn) {
LockstakeUrn(urn).getReward(farm, msg.sender);
emit GetReward(urn, farm);
}
Expand Down
2 changes: 1 addition & 1 deletion test/LockstakeEngine.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ contract AllocatorVaultTest is DssTest {
urnOwnersMethods[8] = engine.getReward.selector;

vm.startPrank(address(0xBEEF));
checkModifier(address(engine), "LockstakeEngine/not-urn-owner", urnOwnersMethods);
checkModifier(address(engine), "LockstakeEngine/urn-not-authorized", urnOwnersMethods);
vm.stopPrank();
}

Expand Down

0 comments on commit 2deb688

Please sign in to comment.