Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testing #1454

Closed
wants to merge 17 commits into from
Prev Previous commit
Next Next commit
Update SSQ.sol
shotaronowhere committed Apr 11, 2022

Verified

This commit was signed with the committer’s verified signature.
commit 1449c8eec1b45399f38142e961c0cf99f3446e35
197 changes: 77 additions & 120 deletions contracts/src/libraries/SSQ.sol
Original file line number Diff line number Diff line change
@@ -15,159 +15,116 @@ library SimpleSquanch {
function squanch(bytes32[] calldata _input) public pure returns (bytes32[] memory _result){

assembly {
_result := mload(0x40)
let lengthInput := calldataload(0x24)
let _cursor := add(_result,0x40) // skip length and starting from right to left
for { let i := 0x0} lt(i, lengthInput) { i:= add(i, 0x01)}{
_result := mload(0x40) // free memory pointer
let lengthInput := calldataload(0x24) // skip 4 bytes function selector
let _cursor := add(_result,0x3F) // skip length and starting from right to left
for { let i := 0} lt(i, lengthInput) { i:= add(i, 1)}{

let _encodedInputSlot := encode(calldataload(add(mul(0x20,i),0x44)))

let inputCursor := 1
for {} gt(_encodedInputSlot, 0x00) { }{
mstore8(sub(_cursor,inputCursor),_encodedInputSlot)
inputCursor := add(inputCursor,0x01)
_encodedInputSlot := shr(8,_encodedInputSlot)
if eq(mod(sub(_cursor,sub(inputCursor,0x01)),0x20),0) {
_cursor := add(sub(_cursor,sub(inputCursor,0x01)),0x40)
inputCursor := 1
if eq(_encodedInputSlot,0){
mstore8(_cursor,0)
switch mod(sub(_cursor,_result),0x20)
case 0{
_cursor := add(_cursor,0x3F)
}
default{
_cursor := sub(_cursor,1)
}
}
_cursor := sub(_cursor,sub(inputCursor,0x01))
}

mstore(_result,div(sub(_cursor,_result),0x20)) // store length
mstore(0x40, add(_cursor,0x60)) // Update/return the result array ofsset + length of the data (=i*32)

function encode(_inputSlot) -> resultSlot {
resultSlot := 0x0
let moreFlag := 0x0
let i := 0x0
for { } true { } {
switch lt(_inputSlot, 0x80)
case true{
resultSlot := add(resultSlot, add( moreFlag , shl(mul(8,i),_inputSlot)))
break
for {} gt(_encodedInputSlot, 0) { }{

mstore8(_cursor,_encodedInputSlot)
_encodedInputSlot := shr(8,_encodedInputSlot)

switch mod(sub(_cursor,_result),0x20)
case 0{
_cursor := add(_cursor,0x3F)
}
default{
moreFlag := add(0x80, shl(0x8,moreFlag))
resultSlot := add(resultSlot,shl(mul(8,i),and(_inputSlot, 0x7F)))
i := add(i,0x1)
_inputSlot := shr(7,_inputSlot)
continue
_cursor := sub(_cursor,1)
}
break
}
}

switch mod(sub(_cursor,_result),0x20)
case 0x1F{
mstore(_result,sub(div(sub(_cursor,_result),0x20),1)) // store length
_cursor := sub(_cursor,0x1F)
mstore(0x40, _cursor)
}
default{
mstore(_result,div(sub(_cursor,_result),0x20)) // store length
_cursor := add(_cursor,sub(0x20, mod(sub(_cursor,_result),0x20)))
mstore(0x40, _cursor)
}

function encode(_inputSlot) -> _resultSlot {
let i := 0
for { } gt(_inputSlot,0x7F) {i := add(i,1)} {
_resultSlot := add(_resultSlot,shl(mul(8,i),add(0x80,and(_inputSlot, 0x7F))))
_inputSlot := shr(7,_inputSlot)
}
_resultSlot := add(_resultSlot,shl(mul(8,i),and(_inputSlot, 0x7F)))
}
}
}

// TODO : Fix bugs with unsquanching _input for length > 1
function unsquanch(bytes32[] calldata _input) public pure returns (bytes32[] memory _result){

assembly {

_result := mload(0x40)
let _cursorResult := add(_result,0x20)
let counter :=0
let decodedCursorLast := 0
let encodedLength := calldataload(0x24)
let currentEncoded := calldataload(0x44)
let NextEncoded := 0
for {} lt(counter,encodedLength) {} {
let _decodedInputSlot, decodedCursor , complete:= decode(currentEncoded)
switch complete
case true{
mstore(_cursorResult, _decodedInputSlot)
_cursorResult := add(_cursorResult, 0x20)
if gt(decodedCursorLast,0){
decodedCursor := sub(decodedCursor,decodedCursorLast)
decodedCursorLast := 0
currentEncoded := NextEncoded
counter := add(counter,0x01)
}
currentEncoded := shr(mul(8,decodedCursor),currentEncoded)
if eq(currentEncoded,0){
counter := add(counter, 0x01)
if lt(counter,encodedLength){
currentEncoded := calldataload(add(0x44,mul(counter,0x20)))
}
}
}
default {
NextEncoded := calldataload(add(0x44,mul(add(counter,0x01),0x20)))
decodedCursorLast := decodedCursor
currentEncoded := add(shl(mul(8,decodedCursor),NextEncoded),currentEncoded)
}
}
let cursor := add(_result,0x20)
let calldataCursor := 0x24
let encodedLength := calldataload(calldataCursor)

mstore(_result,sub(div(sub(_cursorResult,_result),0x20),0x01)) // store length
mstore(0x40, _cursorResult) // Update/return the result array ofsset + length of the data (=i*32)

function decode(_inputSlot) -> _resultSlot, _cursorProgress, _complete{
_resultSlot := 0x0
_cursorProgress := 0x0
_complete := true
for { } true { } {
_resultSlot := add(_resultSlot,shl(mul(7,_cursorProgress),and(_inputSlot, 0x7F)))
switch eq(and(_inputSlot, 0x80),0)
case true{
_cursorProgress := add(_cursorProgress,0x1)
if eq(_inputSlot,0 ){
_complete := false
_cursorProgress := sub(_cursorProgress,0x1)
}
break
let encoded := 0
let decoded := 0

let decodedIndex := 0
for { let i := 0} lt(i,encodedLength) {i := add(i,1)} {
calldataCursor := add(calldataCursor,0x20)
encoded := calldataload(calldataCursor)

for { let j := 0 } lt(j,0x20) {j := add(j,1)} {
decoded := add(decoded,shl(mul(7,decodedIndex),and(encoded, 0x7F)))
switch and(encoded,0x80)
case 0{
mstore(cursor,decoded)
cursor := add(cursor,0x20)
decoded := 0
decodedIndex := 0
}
default{
_inputSlot := shr(8,_inputSlot)
_cursorProgress := add(_cursorProgress,0x1)
continue
decodedIndex := add(decodedIndex, 1)
}
break
encoded := shr(8,encoded)
}
}

mstore(_result,sub(div(sub(cursor,_result),0x20),0x01)) // store length
mstore(0x40, cursor) // Update/return the result array ofsset + length of the data (=i*32)

}
}

function encode(bytes32 _input) public pure returns (bytes32 result){
function encode(bytes32 _input) public pure returns (bytes32 _result){
assembly {
result := 0x0
let moreFlag := 0x0
let i := 0x0
for { } true { } {
switch lt(_input, 0x80)
case true{
result := add(result, add( moreFlag , shl(mul(8,i),_input)))
break
}
default{
moreFlag := add(0x80, shl(0x8,moreFlag))
result := add(result,shl(mul(8,i),and(_input, 0x7F)))
i := add(i,0x1)
_input := shr(7,_input)
continue
}
break
let i := 0
for { } gt(_input,0x7F) {i := add(i,1)} {
_result := add(_result,shl(mul(8,i),add(0x80,and(_input, 0x7F))))
_input := shr(7,_input)
}
_result := add(_result,shl(mul(8,i),and(_input, 0x7F)))
}
}

function decode(bytes32 _input) public pure returns (bytes32 result){
function decode(bytes32 _input) public pure returns (bytes32 _result){
assembly {
result := 0x0
let i := 0x0
for { } true { } {
result := add(result,shl(mul(7,i),and(_input, 0x7F)))
switch eq(and(_input, 0x80),0)
case true{
break
}
default{
_input := shr(8,_input)
i := add(i,0x1)
continue
}
break
for { let i := 0x0 } gt(_input,0) {i := add(i,0x1)} {
_result := add(_result,shl(mul(7,i),and(_input, 0x7F)))
_input := shr(8,_input)
}
}
}