Problems with return multiples arrays (overflow)

When i try to return a object with 3 arrays he only works if only 1 array have information, if 2 or more arrays have information revert...

Example of execution:

(tests1 != empty
teste2 == empty
teste3 == empty) == it works

(tests1 == empty
teste2 != empty
teste3 == empty) == it works

(tests1 == empty
teste2 == empty
teste3 != empty) == it works

(tests1 != empty
teste2 != empty
teste3 == empty) == does not work

(tests1 == empty
teste2 != empty
teste3 != empty) == does not work

Error output :roll_eyes::

{ "error": "Failed to decode output: Error: overflow (fault="overflow", operation="toNumber", value="35408467139433450592217433187231851964531694900788300625387963629091585785856", code=NUMERIC_FAULT, version=bignumber/5.4.1)" }

Code:

struct STest1 {
    address sender;
    uint id;
    uint weiAmount;
    uint timeStamp;
}

struct STest2 {
    address sender;
    address payer;
    uint weiAmount;
    uint timeStamp;
}

struct STest3 {
    address sender;
    address payer;
    uint weiAmount;
    uint timeStamp;
}

struct SBonus {
    STest1[] tests1;
    STest2[] tests2;
    STest3[] tests3;
}


function getBonusByAddress() public view returns(SBonus memory _bonus) {
    STest1[] memory tests1 = new STest1[](Tests1Lenght);
    for (uint i = 0; i < Counter; i++) {
        if (Tests1[i].sender == msg.sender) {
            tests1[i] = Tests1[i];
        }
    }
    STest2[] memory tests2 = new STest2[](Tests2Lenght);
    for (uint ii = 0; ii < Counter; ii++) {
        if (Tests2[ii].sender == msg.sender) {
            tests2[ii] = Tests2[ii];
        }
    }
    STest3[] memory tests3 = new STest3[](Tests3Lenght);
    for (uint iii = 0; iii < Counter; iii++) {
        if (Tests3[iii].sender == msg.sender) {
            tests3[iii] = Tests3[iii];
        }
    }
    
    _bonus = SBonus({
        tests1: tests1,
        tests2: tests2,
        tests3: tests3
    });
    

    return(_bonus);
    // emit Event( tests1, tests2, tests3 );

}

Can someone help me please? I've been at it for 2 days :frowning:

Can you explain what exactly are you trying to do? Maybe we can come up w/ a different design. I'm not sure what's wrong with your code from the snippet you sent (aside from the fact that it looks very inefficient).

Thanks for the feedback.

It's my first contract, so every tips is welcome, how could i increase the efficiency of my code?

The main idea is create a simple DAPP to hold ETH value, like an escrow, so i have 3 structs arrays, (open, paid, canceled) in this case i need to search for the sender in 3 arrays and return.
Is the way I'm doing it correct?
Can I make a DAPP with just the blockchain (no database needed)?

Is the way I'm doing it correct?

There's no right or wrong approach tbrh though a simple optimisation could be to reduce the number of loops i.e.

    STest1[] memory tests1 = new STest1[](Tests1Lenght);
    STest2[] memory tests2 = new STest2[](Tests2Lenght);
    STest3[] memory tests3 = new STest3[](Tests3Lenght);
    for (uint i = 0; i < Counter; i++) {
        if (Tests1[i].sender == msg.sender) {
            tests1[i] = Tests1[i];
        }

        if (Tests2[ii].sender == msg.sender) {
            tests2[ii] = Tests2[ii];
        }

        if (Tests3[iii].sender == msg.sender) {
            tests3[iii] = Tests3[iii];
        }
    }

Personally, I would take advantage of mappings to track for each category (open, paid, cancelled) so you can avoid the looping entirely.

Can I make a DAPP with just the blockchain (no database needed)?

Yep

Oh, sorry, when a make this snippet didn't end up paying attention...

I think I found the problem...
Maybe it's the fault of delete Tests1[i], Tests2[i] and Tests3[i], when i use the delete i has creating a gap in the array.

I think the source of the problem starts here:

function payTest1(uint _index) public payable {
    Tests2[_index] = STest2({ 
        sender: Tests1[_index].sender, 
        payer: msg.sender, 
        weiAmount: Tests1[_index].weiAmount,
        timeStamp: Tests1[_index].timeStamp
    });
    Tests2Lenght++;
    Tests1Lenght--;
    delete Tests1[_index];
}

If i try with Count instead Test[1,2,3]Lenght it work... sounds like i break the array because of my lenght variable...

When i create an test1 i use Tests1Lenght++;
When i update an test1 to test2 i use Tests1Lenght-- && Tests2Lenght++;

What would be the best approach for this?
Any idea?

Thanks for everything

Update:

The problem is:
When i run the for in Counter, the counter can be more then test[1,2,3]lenght so he try to create a position like test1[counter] but the counter is bigger then test1lenght and i use the test1lenght to define the size of the array (STest1 memory tests1 = new STest1;). :confused:

Any tips are welcome :roll_eyes:

struct STest1 {
    address sender;
    uint id;
    uint weiAmount;
    uint timeStamp;
}

struct STest2 {
    address sender;
    address payer;
    uint weiAmount;
    uint timeStamp;
}

struct STest3 {
    address sender;
    address payer;
    uint weiAmount;
    uint timeStamp;
}

struct SBonus {
    STest1[] tests1;
    STest2[] tests2;
    STest3[] tests3;
}


function getBonusByAddress() public view returns(SBonus memory _bonus) {
    STest1[] memory tests1 = new STest1[](Tests1Lenght);
    STest2[] memory tests2 = new STest2[](Tests2Lenght);
    STest3[] memory tests3 = new STest3[](Tests3Lenght);

    uint TempTests1Lenght = 0;
    uint TempTests2Lenght = 0;
    uint TempTests3Lenght = 0;

    for (uint i = 0; i < Counter; i++) {
        if (Tests1[i].sender == msg.sender) {
            tests1[TempTests1Lenght] = Tests1[i];
            TempTests1Lenght++;
        }
    
        if (Tests2[i].sender == msg.sender) {
            tests2[TempTests2Lenght] = Tests2[i];
            TempTests2Lenght++;
        }
    
        if (Tests3[iii].sender == msg.sender) {
            tests3[TempTests3Lenght] = Tests3[i];
            TempTests3Lenght++;
        }
    }
    
    _bonus = SBonus({
        tests1: tests1,
        tests2: tests2,
        tests3: tests3
    });
    

    return(_bonus);
    // emit Event( tests1, tests2, tests3 );

}