GithubHelp home page GithubHelp logo

Comments (13)

JGcarv avatar JGcarv commented on July 17, 2024

Hello @izqui , I would like to tackle this one! Although the solution itself is quite simple, I'm a bit afraid to put things in the wrong place, given the somewhat complex architecture.

My main question is, should I implement a whitelistToken(address token) function in the bylaw app itself? Because it seems a bit off place, as the bylawas app mostly defines the types of ByLaws and how to resolve them.

And related to this, the whitelistToken(address token) function itself should be restricted, or it wouldn't make a difference because the malicious token could call it, and therefore should be govern by a bylaw policy, but which one? Or should be open by default and linked to a specific kind later on?

Thanks in advance for the help!

from aragonos.

izqui avatar izqui commented on July 17, 2024

Hello @JGcarv, sorry for the delay.

I think it would make sense to make it as a 'global setting' to all bylaws, an automatically reject actions in which the token is not in the whitelist.

The whitelistToken(...) function should definitely be protected with a onlyDAO modifier so it gets protected with bylaws (how meta ;))

from aragonos.

JGcarv avatar JGcarv commented on July 17, 2024

Thanks for the responde @izqui!

Just a few more question:
What should be the behavior of tokenized eth? Allowed by default?

Also, when dealing with ether, canPerformAction is always called with 0 for token or it sometimes uses EtherToken address?

from aragonos.

izqui avatar izqui commented on July 17, 2024

That's a very good question.

There are two different cases:

  • When a 'vanilla transaction' is done, in which the token value is '0'. For this case I think it should always be allowed (no way to trick the sender using ETH transactions).
  • When a token transaction is done using the EtherToken (token is ethertoken address), then it should be treated as any other token and only allowed if whitelisted.

Even though the EtherToken should be explicitly whitelisted if trusted to do token transfers, it could be whitelisted by default configuration.

from aragonos.

izqui avatar izqui commented on July 17, 2024

A problem with the whitelist is that it will block all token deposits from not whitelisted tokens (which I don't think it is the expected behavior).

The problem solved with this is not allowing impersonations because of using untrusted tokens, so there is no problem to allow transactions that don't execute anything.

This would require changing the Kernel dispatch function checks order like this:

Current:

function dispatch(address _sender, address _token, uint256 _value, bytes _payload) internal {
        require(canPerformAction(_sender, _token, _value, _payload));
        vaultDeposit(_token, _value); // deposit tokens that come with the call in the vault
        if (_payload.length == 0) return; // Just receive the tokens

New:

function dispatch(address _sender, address _token, uint256 _value, bytes _payload) internal {
        vaultDeposit(_token, _value); // deposit tokens that come with the call in the vault
        if (_payload.length == 0) return; // Just receive the tokens
        require(canPerformAction(_sender, _token, _value, _payload));

from aragonos.

izqui avatar izqui commented on July 17, 2024

Also receiveApproval(address _sender, uint256 _value, address _token, bytes _data) method is sometimes used even if the token is not calling it (see we use the _token parameter as the token).

This allows for trustless deposits of tokens (while being able to account for it). The problem is that the _sender parameter and _data can only be trusted that it came from the token in the case that _token == msg.sender.

I would modify the dispatch call in receiveApproval to: dispatch(_token == msg.sender ? _sender : msg.sender, _token, _value, _token == msg.sender ? _data : new bytes(0));

from aragonos.

JGcarv avatar JGcarv commented on July 17, 2024

Thanks for the answer! I'm already testing the modifications, but I'm seriously stuck here, for some reason, I cannot make it work.

Now, reading the code, I stumbled across a comment in VaultOrgan.sol that says:

@dev deposit is not reachable on purpose using normal dispatch route

What does that mean? It should be reachable, since the dispatch in Kernel.sol calls vaultDeposit, which makes the deposit correct? Or I am missing something? Can this be the reason the deposits are not working on the tests?

from aragonos.

JGcarv avatar JGcarv commented on July 17, 2024

I've investigated a bit, and I feel like there's a problem with the deposit function in the VaultOrgan. Look:

function deposit(address _token, uint256 _amount)
    check_blacklist(_token)
    external
    payable
    {
        if (_amount == 0)
            return;
        if (_token == 0 && msg.value == _amount)
            tokenizeEther(_amount); // if call has ETH, we tokenize it

        address token = _token == 0 ? getEtherToken() : _token;

        uint256 currentBalance = getTokenBalance(token);
        // This will actually be dispatched every time balance goes from 0 to non-zero.
        // The idea is that the frontend can listen for this event in all DAO history.
        // TODO: Is an event for when a certain token balance goes to 0 needed?
        if (currentBalance == 0)
            NewTokenDeposit(token);

        // TODO: Aragon Network funds redirect goes here :)

        uint256 newBalance = safeAdd(currentBalance, _amount); // - aragonNetworkFee;
        // Check token balance isn't less than expected.
        // Could be less because of a faulty erc20 implementation (can't trust)
        // Could be more because a token transfer can be done without notifying
        assert(newBalance <= ERC20(token).balanceOf(this));

        setTokenBalance(token, newBalance);
        Deposit(token, dao_msg().sender, _amount);
    }

If the token in question is an ERC223 token, it implements the transfer function that calls tokenFallback, which is implemented in the Kernel and calls the deposit function above.

Now , in the assert(newBalance <= ERC20(token).balanceOf(this)); line the token transfer transaction hasn't yet finished, so the balanceOf(this) is still a lower value than the newBalance making the whole transaction fail.

from aragonos.

izqui avatar izqui commented on July 17, 2024

Most ERC223 implementations (including the one in test/helpers) change the token balance before making the call to the receiver, therefore even though the call hasn't 'finished' if the receiver were to make a check of the balance, it should already be updated.

Also why do you say deposits are not working on the tests? All tests from master are passing AFAIK, including the 'test/dao_dispatch.js' tests where erc223 is tested

from aragonos.

JGcarv avatar JGcarv commented on July 17, 2024

Damn, that makes sense. Now I don't really know what I was thinking before to come to that conclusion.

Thanks for the insight

from aragonos.

izqui avatar izqui commented on July 17, 2024

Did you solve it? If you published a draft PR i could try to help finding the issue!

from aragonos.

izqui avatar izqui commented on July 17, 2024

Hi @JGcarv! How is progress going? i'd love to get this merged this week

from aragonos.

JGcarv avatar JGcarv commented on July 17, 2024

Hey! I haven't done any progress, to be honest.

Somehow testing this contract is pretty frustrating, as nothing behaves as I expected(And I tried many variations).

I'll make a PR in a minute with my current state and hopefully you can shed some light on this.

from aragonos.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.