59850 sc high users funds stuck in the contract permanently
Previous59844 sc insight incorrect and misleading events when adding levels in stargatenft Next59863 sc high over claim of delegation rewards after exit
Was this helpful?
Was this helpful?
_updatePeriodEffectiveStake($, delegation.validator, _tokenId, completedPeriods + 2, false);if (nextClaimablePeriod < currentValidatorPeriod) {
return (nextClaimablePeriod, completedPeriods);
}uint256 claimableAmount = _claimableRewards($, _tokenId, 0);unstake(tokenId2)
/// @inheritdoc IStargate
function unstake(
uint256 _tokenId
) external whenNotPaused onlyTokenOwner(_tokenId) nonReentrant {
........................................................
// ensure that the rewards are claimed
@>> _claimRewards($, _tokenId);
// reset the mappings in storage regarding this delegation
_resetDelegationDetails($, _tokenId);
// burn the token
$.stargateNFTContract.burn(_tokenId);
// validate the contract has enough VET to transfer to the caller
if (address(this).balance < token.vetAmountStaked) {
revert InsufficientContractBalance(address(this).balance, token.vetAmountStaked);
}
// transfer the VET to the caller (which is also the owner of the NFT since only the owner can unstake)
(bool success, ) = msg.sender.call{ value: token.vetAmountStaked }("");
if (!success) {
revert VetTransferFailed(msg.sender, token.vetAmountStaked);
}
}yarn hardhat test --network vechain_solo test/integration/Delegation.test.tsit.only("VTHO rewards gets stolen by exited delegator and funds stuck due to insufficient VTHO balance.", async () => {
const paramsKey = "0x00000000000064656c656761746f722d636f6e74726163742d61646472657373";
const stargateAddress = await protocolParamsContract.get(paramsKey);
const expectedParamsVal = BigInt(await stargateContract.getAddress());
expect(stargateAddress).to.equal(expectedParamsVal);
const validatorAddress = await protocolStakerContract.firstActive();
expect(compareAddresses(validatorAddress, deployer.address)).to.be.true;
const [leaderGroupSize, queuedValidators] =
await protocolStakerContract.getValidationsNum();
expect(leaderGroupSize).to.equal(1);
expect(queuedValidators).to.equal(0);
// staking the token here
const levelId = 1;
const levelSpec = await stargateNFTContract.getLevel(levelId);
const levelVetAmountRequired = levelSpec.vetAmountRequiredToStake;
// Stake an NFT of level 1
let stakeTx = await stargateContract
.connect(user)
.stake(levelId, { value: levelVetAmountRequired });
await stakeTx.wait();
log("\nπ Correctly staked an NFT of level", levelId);
const tokenId1 = await stargateNFTContract.getCurrentTokenId();
// Fast-forward until the NFT is mature
await mineBlocks(Number(levelSpec.maturityBlocks));
log("\nπ Fast-forwarded", Number(levelSpec.maturityBlocks), "blocks to mature the NFT");
stakeTx = await stargateContract
.connect(user)
.stake(levelId, { value: levelVetAmountRequired });
await stakeTx.wait();
log("\nπ Correctly staked an NFT of level", levelId);
// Fast-forward until the NFT is mature
await mineBlocks(Number(levelSpec.maturityBlocks));
log("\nπ Fast-forwarded", Number(levelSpec.maturityBlocks), "blocks to mature the NFT");
const tokenId2 = await stargateNFTContract.getCurrentTokenId();
let delegateTx = await stargateContract.connect(user).delegate(tokenId1, deployer.address);
await delegateTx.wait();
console.log("\nπ Correctly delegated the NFT to validator", deployer.address);
delegateTx = await stargateContract.connect(user).delegate(tokenId2, deployer.address);
await delegateTx.wait();
console.log("\nπ Correctly delegated the NFT to validator", deployer.address);
const [period, startBlock, ,] = await protocolStakerContract.getValidationPeriodDetails(
deployer.address
);
await fastForwardValidatorPeriods(
Number(period),
Number(startBlock),
4
);
await stargateContract.connect(user).requestDelegationExit(tokenId1);
await fastForwardValidatorPeriods(
Number(period),
Number(startBlock),
0
);
// let delegation = await stargateContract.getDelegationDetails(tokenId1);
let status = await stargateContract.getDelegationStatus(tokenId1);
console.log("status exit of delegation: ", status);
let [first, last] = await stargateContract.claimableDelegationPeriods(tokenId1);
console.log(first, last);
await stargateContract.connect(user).claimRewards(tokenId1);
await fastForwardValidatorPeriods(
Number(period),
Number(startBlock),
4
);
// showing the user can also claim for another rewards
[first, last] = await stargateContract.claimableDelegationPeriods(tokenId1);
console.log(first, last);
// claims another period again even though he is already exited
await stargateContract.connect(user).claimRewards(tokenId1);
// tokenId2 now won't be able to exit due to insufficient token balance
// request to exit the delegation and exit for delegator 2
await stargateContract.connect(user).requestDelegationExit(tokenId2);
await fastForwardValidatorPeriods(
Number(period),
Number(startBlock),
0
);
await expect(
stargateContract.connect(user).unstake(tokenId2)).to.be.rejectedWith("builtin: insufficient balance");
});π Correctly delegated the NFT to validator 0xf077b491b355E64048cE21E3A6Fc4751eEeA77fa
π Correctly delegated the NFT to validator 0xf077b491b355E64048cE21E3A6Fc4751eEeA77fa
status exit of delegation: 3n
2n 6n
7n 11n
β VTHO rewards gets stucked and accumulate in contracts. (54573ms)
1 passing (60s)