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

Malicious or hacked admin can drain all tokens #17

Closed
code423n4 opened this issue Oct 28, 2022 · 5 comments
Closed

Malicious or hacked admin can drain all tokens #17

code423n4 opened this issue Oct 28, 2022 · 5 comments
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working duplicate-68 satisfactory satisfies C4 submission criteria; eligible for awards sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")

Comments

@code423n4
Copy link
Contributor

Lines of code

https://github.com/code-423n4/2022-10-paladin/blob/main/contracts/WardenPledge.sol#L653-L661
https://github.com/code-423n4/2022-10-paladin/blob/main/contracts/WardenPledge.sol#L585-L592

Vulnerability details

Impact

Hacked or malicious admin can transfer all tokens of WardenPledge to himself.

Proof of Concept

WardenPledge.recoverERC20 function allows to transfer tokens controlled by contract if the token is not whitelisted.

    function recoverERC20(address token) external onlyOwner returns(bool) {
        if(minAmountRewardToken[token] != 0) revert Errors.CannotRecoverToken();


        uint256 amount = IERC20(token).balanceOf(address(this));
        if(amount == 0) revert Errors.NullValue();
        IERC20(token).safeTransfer(owner(), amount);


        return true;
    }

The check if(minAmountRewardToken[token] != 0) revert Errors.CannotRecoverToken(); is done to not allow admin to send tokens that are used for sending rewards to himself.
But there is another function that allows admin to remove token from whitelisted.

    function removeRewardToken(address token) external onlyOwner {
        if(token == address(0)) revert Errors.ZeroAddress();
        if(minAmountRewardToken[token] == 0) revert Errors.NotAllowedToken();
        
        minAmountRewardToken[token] = 0;
        
        emit RemoveRewardToken(token);
    }

Using this function admin can first remove token from whitelisted and then recover tokens to himself.

I believe this is important thing and protocol should secure this. Because even if admin is not malicious, but ownership somehow was hacked, this gives ability for the attacker to get all funds and pausing can't help here.

Tools Used

VsCode

Recommended Mitigation Steps

You can disallow to blocklist token if the WardenPledge balance is not 0.

@code423n4 code423n4 added 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working labels Oct 28, 2022
code423n4 added a commit that referenced this issue Oct 28, 2022
@Kogaroshi
Copy link

PoC of the Issue is correct, but Remediation brings another issue in the system: in the case of a malicious or bugged token that was whitelisted, and currently in use for a Pledge, that needs to be removed from the whitelist, this would be impossible because the contract balance won't be 0.

Will look for an in-between that could prevent the scenario doing most of the damages to the system.

This was referenced Oct 30, 2022
@Kogaroshi
Copy link

Kogaroshi commented Nov 1, 2022

Fixed in PR 2, commit
Decided on a different way to fix this:

  • tracking all token amounts currently belonging to Pledges
  • change the recoverERC20() method to ignore the whitelist, but forbidding the method to touch any token belonging to Pledges.

That way, admin has no way to touch any Pledge rewards or rug any funds, even after removing a token from the whitelist.
The new system also allows to retrieve the reward token sent directly to the contract by mistake, without touching any Pledge rewards.

@Kogaroshi Kogaroshi added the sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity") label Nov 1, 2022
@c4-judge
Copy link
Contributor

c4-judge commented Nov 9, 2022

kirk-baird marked the issue as satisfactory

@c4-judge c4-judge added satisfactory satisfies C4 submission criteria; eligible for awards primary issue Highest quality submission among a set of duplicates labels Nov 9, 2022
@c4-judge
Copy link
Contributor

c4-judge commented Nov 9, 2022

kirk-baird marked the issue as primary issue

@c4-judge
Copy link
Contributor

c4-judge commented Dec 6, 2022

Simon-Busch marked the issue as duplicate of #68

@c4-judge c4-judge added duplicate-68 and removed primary issue Highest quality submission among a set of duplicates labels Dec 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working duplicate-68 satisfactory satisfies C4 submission criteria; eligible for awards sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
Projects
None yet
Development

No branches or pull requests

4 participants