Error on array pop

Hi,

I have a function to modify an array, if I comment out the .pop() line, it passes, if not, I get this error:

VM error.revert

Code:

function moveShipsToSpace(uint[] memory ships, uint16 fromSpace, uint16 toSpace) public{
         
         for(uint8 i= 0; i<ships.length; i++) { 
            require(containsInSpace(ships[i],fromSpace), "dont have that ship");            
            // Move the last element into the place to delete
            whichShipsAtSpace[msg.sender][fromSpace][i] = whichShipsAtSpace[msg.sender][fromSpace][whichShipsAtSpace[msg.sender][fromSpace].length - 1];
            // Delete
            whichShipsAtSpace[msg.sender][fromSpace].pop();
            // Insert in new location
            whichShipsAtSpace[msg.sender][toSpace].push(shipsArray(ships[i]));
            emit LogUint(ships[i]);
         }
    }

Also, if I pass a single number, it passes with .pop(), so not sure what is the issue, please halp!

1 Like

You have concluded that the revert occurs at the arr.pop() statement.

But if the arr.pop() statement reverts, then so should the expression arr[arr.length - 1] which precedes it in your code.

And since your code does not revert when you remove the arr.pop() statement, we know that the expression arr[arr.length - 1] does not revert either.

Therefore, the conclusion is that your code reverts after the arr.pop() statement.

And what do we have there?

The vague statement whichShipsAtSpace[msg.sender][toSpace].push(shipsArray(ships[i]));, which similarly to the rest of what you've posted, lacks a significant amount of information required in order to determine what the problem is.

So you can either post some more information here, of both the contract code, and the offchain code used for interacting with the contract and testing it. Or you can refocus your investigation on that last statement and try to figure it out.

My guess - the shipsArray function attempts to access an element in the whichShipsAtSpace[msg.sender][fromSpace] array, which at that point is already empty.

1 Like

BTW, a simple way to test my hypothesis above, is to add a revert("123") statement right after the pop statement in your code, and then see what you get printed.
Alternatively, if you happen to be using HardHat, then you can import "hardhat/console.sol" at the top of your contract file, and then add a few console.log statements in that function, which will help you figuring out exactly what the problem is.

Yes, the code was trying to access an empty element in the array.
Thanks!!!