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

Auto shrink address and validate bytes size #30

Merged
merged 4 commits into from Mar 9, 2019
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

@@ -1,7 +1,6 @@
pragma solidity ^0.5.0;

import "./Marmo.sol";
import "./commons/Bytes.sol";
import "./commons/MinimalProxy.sol";


@@ -25,17 +24,15 @@ contract MarmoStork {

// Creates a new MarmoStork (Marmo wallet Factory)
// with wallets pointing to the _source contract reference
// notice: _source may contain less than 20 bytes
// the difference will be filled with 0s at the beginning of the address
constructor(bytes memory _source) public {
constructor(address payable _source) public {
// Generate and save wallet creator bytecode using the provided '_source'
bytecode = MinimalProxy.build(_source);

// Precalculate init_code hash
hash = keccak256(bytecode);

// Destroy the '_source' provided, if is not destroyed
Marmo marmoc = Marmo(Bytes.toAddress(_source));
Marmo marmoc = Marmo(_source);
if (marmoc.signer() == address(0)) {
marmoc.init(address(65536));
}
@@ -63,4 +63,32 @@ library Bytes {
b := shr(mul(sub(32, mload(_a)), 8), mload(add(_a, 32)))
}
}

// Returns the most significant bit of a given uint256
function mostSignificantBit(uint256 x) internal pure returns (uint256) {
uint8 o = 0;
uint8 h = 255;

while (h > o) {
uint8 m = uint8 ((uint16 (o) + uint16 (h)) >> 1);
uint256 t = x >> m;
if (t == 0) h = m - 1;
else if (t > 1) o = m + 1;
else return m;
}

return h;
}

// Shrinks a given address to the minimal representation in a bytes array
function shrink(address _a) internal pure returns (bytes memory b) {
uint256 abits = mostSignificantBit(uint256(_a)) + 1;
uint256 abytes = abits / 8 + (abits % 8 == 0 ? 0 : 1);

assembly {
b := 0x0
mstore(0x0, abytes)
mstore(0x20, shl(mul(sub(32, abytes), 8), _a))
}
}
}
@@ -4,7 +4,6 @@ import "./Bytes.sol";


library MinimalProxy {
using Bytes for address;
using Bytes for bytes1;
using Bytes for bytes;

@@ -20,7 +19,14 @@ library MinimalProxy {
bytes1 constant PUSH_1 = 0x60;
bytes1 constant BASE_RETURN_JUMP = 0x1b;

function build(bytes memory _address) internal pure returns (bytes memory initCode) {
// Returns the Init code to create a
// Minimal proxy pointing to a given address
function build(address _address) internal pure returns (bytes memory initCode) {
return build(Bytes.shrink(_address));
}

function build(bytes memory _address) private pure returns (bytes memory initCode) {
require(_address.length <= 20, "Address too long");
initCode = Bytes.concat(
CODE1,
BASE_SIZE.plus(_address.length).toBytes(),
@@ -5,4 +5,4 @@ import "../MarmoStork.sol";
/* solium-disable-next-line */
// Easy deploy of MarmoStork
// create MarmoSource and deploy MarmoStork using that source
contract MarmoStorkAuto is MarmoStork(abi.encodePacked(new Marmo())) { }
contract MarmoStorkAuto is MarmoStork(address(new Marmo())) { }
@@ -25,4 +25,44 @@ contract TestBytes {
"Should decode address of 5 bytes"
);
}

function testShrink() external {
address a = address(0x000000000000000000000000000000fAa21D387c);
bytes memory ashrunk = Bytes.shrink(a);
Assert.equal(
keccak256(hex"faa21d387c"),
keccak256(ashrunk),
"Should shrink the address"
);
Assert.equal(
Bytes.toAddress(ashrunk),
a,
"Should shrink and expand address"
);
}

function testShirnkSetFloor() external {
bytes memory ashrunk;
for(uint256 i = 0; i < 950; i++) {
ashrunk = Bytes.shrink(address(i));
Assert.equal(
address(i),
Bytes.toAddress(ashrunk),
"Should shrink and expand address"
);
}
}

function testShirnkSetCeiling() external {
bytes memory ashrunk;
uint256 to = (uint256(0) - 1) - 950;
for(uint256 i = (uint256(0) - 1); i > to; i--) {
ashrunk = Bytes.shrink(address(i));
Assert.equal(
address(i),
Bytes.toAddress(ashrunk),
"Should shrink and expand address"
);
}
}
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.