Skip to content

Commit

Permalink
add updateAndWithdraw function to OmnichainStaking
Browse files Browse the repository at this point in the history
  • Loading branch information
oxoxDev committed Aug 6, 2024
1 parent 24bb916 commit eb8c73b
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 22 deletions.
2 changes: 1 addition & 1 deletion contracts/interfaces/IOmnichainStaking.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ interface IOmnichainStaking is IVotes {
// An omni-chain staking contract that allows users to stake their veNFT
// and get some voting power. Once staked the voting power is available cross-chain.

function unstakeToken(uint256 tokenId) external;
function unstakeAndWithdraw(uint256 tokenId) external;

// function totalSupply() external view returns (uint256);

Expand Down
3 changes: 2 additions & 1 deletion contracts/locker/BaseLocker.sol
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,8 @@ contract BaseLocker is
/// @dev Only possible if the lock has expired
function withdraw(uint256 _tokenId) public virtual nonReentrant {
require(
_isAuthorized(ownerOf(_tokenId), msg.sender, _tokenId),
_isAuthorized(ownerOf(_tokenId), msg.sender, _tokenId) ||
address(staking) == msg.sender,
"caller is not owner nor approved"
);

Expand Down
50 changes: 30 additions & 20 deletions contracts/locker/staking/OmnichainStakingBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -165,27 +165,13 @@ abstract contract OmnichainStakingBase is
}

/**
* @dev Unstakes a regular token NFT and transfers it back to the user.
* @param tokenId The ID of the regular token NFT to unstake.
* @notice A single withdraw function to unstake NFT, transfer it back to
* the user, and also withdraw all tokens for `tokenId` from the locker.
* @param tokenId The ID of the regular token NFT to unstake and withdraw.
*/
function unstakeToken(uint256 tokenId) external updateReward(msg.sender) {
require(lockedByToken[tokenId] != address(0), "!tokenId");
address lockedBy_ = lockedByToken[tokenId];
if (_msgSender() != lockedBy_)
revert InvalidUnstaker(_msgSender(), lockedBy_);

delete lockedByToken[tokenId];
lockedTokenIdNfts[_msgSender()] = deleteAnElement(
lockedTokenIdNfts[_msgSender()],
tokenId
);

// reset and burn voting power
_burn(msg.sender, tokenPower[tokenId]);
tokenPower[tokenId] = 0;
votingPowerCombined.reset(msg.sender);

locker.safeTransferFrom(address(this), msg.sender, tokenId);
function unstakeAndWithdraw(uint256 tokenId) external {
_unstakeToken(tokenId);
locker.withdraw(tokenId);
}

/**
Expand Down Expand Up @@ -408,6 +394,30 @@ abstract contract OmnichainStakingBase is
}
}

/**
* @dev Unstakes a regular token NFT and transfers it back to the user.
* @param tokenId The ID of the regular token NFT to unstake.
*/
function _unstakeToken(uint256 tokenId) internal updateReward(msg.sender) {
require(lockedByToken[tokenId] != address(0), "!tokenId");
address lockedBy_ = lockedByToken[tokenId];
if (_msgSender() != lockedBy_)
revert InvalidUnstaker(_msgSender(), lockedBy_);

delete lockedByToken[tokenId];
lockedTokenIdNfts[_msgSender()] = deleteAnElement(
lockedTokenIdNfts[_msgSender()],
tokenId
);

// reset and burn voting power
_burn(msg.sender, tokenPower[tokenId]);
tokenPower[tokenId] = 0;
votingPowerCombined.reset(msg.sender);

locker.safeTransferFrom(address(this), msg.sender, tokenId);
}

/**
* @dev Deletes an element from an array.
* @param elements The array to delete from.
Expand Down

0 comments on commit eb8c73b

Please sign in to comment.