function sell(
        ISetToken set,
        uint256 amountArg,
        IKyberNetworkProxy kyber
    )
        public
    {
        uint256 naturalUnit = set.naturalUnit();
        uint256 amount = amountArg.div(naturalUnit).mul(naturalUnit);

        set.transferFrom(msg.sender, this, amount);
        set.redeem(amount);

        address[] memory components = set.getComponents();

        for (uint i = 0; i < components.length; i++) {
            IERC20 token = IERC20(components[i]);

            if (token.allowance(this, kyber) == 0) {
                require(token.approve(set, uint256(-1)), "Approve failed");
            }

            kyber.tradeWithHint(
                components[i],
                amount,
                ETHER_ADDRESS,
                this,
                1 << 255,
                0,
                0,
                ""
            );

            if (token.balanceOf(this) > 0) {
                require(token.transfer(msg.sender, token.balanceOf(this)), "transfer failed");
            }
        }

        if (address(this).balance > 0) {
            msg.sender.transfer(address(this).balance);
        }
    }