0

Any ideas on how to dynamically create fixed-side arrays that doesn't involve a bunch of if statements?

EDIT:

Got this function that needs to produce a fixed-side array which length would depend on the args passed to it. As you can see, it looks a bit ugly with the if statements and it's not that scalable.

struct TokenLiq {
        uint amountIn;
        uint[2] biLiq;
        uint[3] triLiq;
    }

function _calculateTokenAmount(
   uint amountIn_, 
   uint length_
) private returns(TokenLiq memory tokens) 
{
        uint tokenAmount;

        if (length_ == 3) { 
            uint[3] memory amounts;
            amounts[0] = 0;
            amounts[1] = 0;
            amounts[2] = amountIn_;
            tokenAmount = s.tricrypto.calc_token_amount(amounts, true);
            tokens.amountIn = tokenAmount;
            tokens.triLiq = amounts;
        } else if (length_ == 2) {
            uint[2] memory amounts;
            amounts[0] = 0;
            amounts[1] = amountIn_;
            tokenAmount = s.crv2Pool.calc_token_amount(amounts, true);
            tokens.amountIn = tokenAmount;
            tokens.biLiq = amounts;
        }
}
2
  • Can you show an example or exaplain better? Thank you Mar 25, 2022 at 16:23
  • Done ;) @Kerry99
    – dNyrM
    Mar 25, 2022 at 16:50

1 Answer 1

0

Try this example of smart contract that I created on your piece of code basement:

//SPDX-License-Identifier: MIT
pragma solidity 0.8.0;

contract Test {

    mapping(address => TokenLiq) _liq;

    struct TokenLiq {
        uint amountIn;
        uint[] biLiq;
        uint[] triLiq;
    }

    modifier checkLengthArray(uint _lengthArray, uint _length) {
        require((_lengthArray <= 3 && _lengthArray > 1) &&
                (_length <= 3 && _length > 1), "Error");
        _;        
    }

    function addLiq(uint[] memory amountsArray_, uint length_) public {
        TokenLiq memory t = _calculateTokenAmount(amountsArray_, length_);
        _liq[msg.sender] = t;
    }

    function _calculateTokenAmount(uint[] memory amountsArray_, uint length_) checkLengthArray(amountsArray_.length, length_) private pure returns(TokenLiq memory tokens) 
    {
        uint tokenAmount;
        uint[] memory _amounts = new uint[](length_);
        for(uint i = 0; i < _amounts.length; i++){
            _amounts[i] = amountsArray_[i];
        }

        tokenAmount = s.tricrypto.calc_token_amount(_amounts, true);
        tokens.amountIn = tokenAmount;

        if(_amounts.length == 2)
            tokens.biLiq = _amounts;
        else if(_amounts.length == 3)
            tokens.triLiq = _amounts;
    }

    function _getBiLiq() external view returns(uint[] memory) {
        return _liq[msg.sender].biLiq;
    }

    function _getTriLiq() external view returns(uint[] memory) {
        return _liq[msg.sender].triLiq;
    }

    function _getAmountIn() external view returns(uint) {
        return _liq[msg.sender].amountIn;
    }
}

First of all, I change the fixed size of two array biLiq and triLiq in dynamic size (I don't know if you have possibilities). Then I change the input parameter amountIn_ in an uint array called amountsArray. In this array you must to pass the values in order of index (in your case the value should be: 0,0,amountIn_). Then I created an array dynamic and I set his length with length_ input parameter of _calculateTokenAmount() function and I cycle for the length of amountsArray_ and put into the amountsArray_ value at index i into the _amounts array index. Rest of code and functions are simply to understand. One last thing, I added a checkLengthArray() modifier to restrict the size of array to pass to the function. In this case the array length can be only 2 (biLiq) or 3 (triLiq).

1
  • Thanks for the output! The thing is that I couldn't use dynamic-size arrays since those variables were going to be the params of other functions that only took fixed-size. I ended changing my implementation to avoid this situation
    – dNyrM
    Mar 31, 2022 at 20:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.