Skip to content

Instantly share code, notes, and snippets.

@scammi
Created January 16, 2022 14:55
Show Gist options
  • Save scammi/602387a22e04c77beb73c0ebc0f0bc18 to your computer and use it in GitHub Desktop.
Save scammi/602387a22e04c77beb73c0ebc0f0bc18 to your computer and use it in GitHub Desktop.
Implementation of Fisher-Yates Shuffle in solidity.
pragma solidity ^0.8.0;
contract Shuffle {
uint256[] public shuffle = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47];
uint256 public entropy = block.timestamp;
function shuffleArray() public {
for(uint256 i = shuffle.length -1 ; i > 0; i--) {
uint256 swapIndex = entropy % (shuffle.length - i);
uint256 currentIndex = shuffle[i];
uint256 indexToSwap = shuffle[swapIndex];
shuffle[i] = indexToSwap;
shuffle[swapIndex] = currentIndex;
}
}
}
@CodeSandwich
Copy link

Very clever! But I'm rather certain that there's a bug here.

As of now in the first iteration i == shuffle.length - 1, so

entropy % (shuffle.length - i)
==
entropy % (shuffle.length - shuffle.length + 1)
==
entropy % 1
==
0

It means that the last array item is always swapped with the first one, but it should be swapped with a random item in the array, including itself.

I think that the fix is to:

- uint256 swapIndex = entropy % (shuffle.length - i);
+ uint256 swapIndex = entropy % (i + 1);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment