This commit is contained in:
perissology 2018-02-07 12:52:08 +01:00
parent a79bb5d693
commit 6cdceb62cf
5 changed files with 42 additions and 75 deletions

View File

@ -26,6 +26,10 @@ contract EternalStorage is Escapable {
UIntStorage[record] = value; UIntStorage[record] = value;
} }
function incrementUIntValue(bytes32 record) public returns (uint) {
return UIntStorage[record] += 1;
}
/// Int Storage /// Int Storage
function getIntValue(bytes32 record) public view returns (int) { function getIntValue(bytes32 record) public view returns (int) {
@ -36,6 +40,10 @@ contract EternalStorage is Escapable {
IntStorage[record] = value; IntStorage[record] = value;
} }
function incrementIntValue(bytes32 record) public returns (int) {
return IntStorage[record] += int(1);
}
/// Address Storage /// Address Storage
function getAddressValue(bytes32 record) public view returns (address) { function getAddressValue(bytes32 record) public view returns (address) {

View File

@ -33,47 +33,27 @@ library EternallyPersistentLib {
function stgObjectGetString(EternalStorage _storage, string class, uint id, string fieldName) internal view returns (string) { function stgObjectGetString(EternalStorage _storage, string class, uint id, string fieldName) internal view returns (string) {
bytes32 record = keccak256(class, id, fieldName); bytes32 record = keccak256(class, id, fieldName);
//Function signature bytes4 sig = 0xa209a29c; // bytes4(keccak256("getStringValue(bytes32)"));
bytes4 sig = bytes4(keccak256("getStringValue(bytes32)"));
string memory s; string memory s;
assembly { assembly {
let x := mload(0x40) //Find empty storage location using "free memory pointer" let ptr := mload(0x40) //Find empty storage location using "free memory pointer"
mstore(x, sig) //Place signature at beginning of empty storage mstore(ptr, sig) //Place signature at beginning of empty storage
mstore(add(x, 0x04), record) //Place first argument directly next to signature mstore(add(ptr, 0x04), record) //Place first argument directly next to signature
let success := call(//This is the critical change (Pop the top stack value) let result := staticcall(sub(gas, 10000), _storage, ptr, 0x24, 0, 0)
5000, //5k gas
_storage, //To addr
0, //No value
x, //Inputs are stored at location x
0x24, //Inputs are 36 byes long
x, //Store output over input (saves space)
0x80) //Outputs are 32 bytes long
let strL := mload(add(x, 0x20)) // Load the length of the string let size := returndatasize
returndatacopy(ptr, 0, size) // overwrite ptr to save a bit of gas
jumpi(ask_more, gt(strL, 64)) // revert instead of invalid() bc if the underlying call failed with invalid() it already wasted gas.
// if the call returned error data, forward it
mstore(0x40, add(x, add(strL, 0x40))) switch result case 0 { revert(ptr, size) }
default {
s := add(x, 0x20) mstore(0x40, add(ptr, size)) // update free mem location
// We need to skip the first 32 bytes which contains the start offset of the returned byte array
ask_more : s := add(ptr, 0x20) // set the string
mstore(x, sig) //Place signature at beginning of empty storage }
mstore(add(x, 0x04), record) //Place first argument directly next to signature
success := call(//This is the critical change (Pop the top stack value)
5000, //5k gas
_storage, //To addr
0, //No value
x, //Inputs are stored at location x
0x24, //Inputs are 36 byes long
x, //Store output over input (saves space)
add(0x40, strL)) //Outputs are 32 bytes long
mstore(0x40, add(x, add(strL, 0x40)))
s := add(x, 0x20)
} }
return s; return s;
@ -111,13 +91,7 @@ library EternallyPersistentLib {
// Array // Array
function stgCollectionAddItem(EternalStorage _storage, bytes32 idArray) internal returns (uint) { function stgCollectionAddItem(EternalStorage _storage, bytes32 idArray) internal returns (uint) {
uint length = _storage.getUIntValue(keccak256(idArray, "length")); return _storage.incrementUIntValue(keccak256(idArray, "length"));
// Increment the size of the array
length++;
_storage.setUIntValue(keccak256(idArray, "length"), length);
return length;
} }
function stgCollectionLength(EternalStorage _storage, bytes32 idArray) internal view returns (uint) { function stgCollectionLength(EternalStorage _storage, bytes32 idArray) internal view returns (uint) {

View File

@ -21,7 +21,7 @@ pragma solidity ^0.4.11;
import "./LiquidPledgingBase.sol"; import "./LiquidPledgingBase.sol";
/// @dev `LiquidPleding` allows for liquid pledging through the use of /// @dev `LiquidPledging` allows for liquid pledging through the use of
/// internal id structures and delegate chaining. All basic operations for /// internal id structures and delegate chaining. All basic operations for
/// handling liquid pledging are supplied as well as plugin features /// handling liquid pledging are supplied as well as plugin features
/// to allow for expanded functionality. /// to allow for expanded functionality.
@ -106,9 +106,8 @@ contract LiquidPledging is LiquidPledgingBase {
{ {
checkAdminOwner(idSender); checkAdminOwner(idSender);
idPledge = normalizePledge(idPledge); Pledges.Pledge memory p = normalizePledge(idPledge);
Pledges.Pledge memory p = findPledge(idPledge);
PledgeAdminType receiverAdminType = getAdminType(idReceiver); PledgeAdminType receiverAdminType = getAdminType(idReceiver);
require(p.pledgeState == Pledges.PledgeState.Pledged); require(p.pledgeState == Pledges.PledgeState.Pledged);
@ -229,8 +228,8 @@ contract LiquidPledging is LiquidPledgingBase {
/// @param idPledge Id of the pledge that is to be redeemed into ether /// @param idPledge Id of the pledge that is to be redeemed into ether
/// @param amount Quantity of ether (in wei) to be authorized /// @param amount Quantity of ether (in wei) to be authorized
function withdraw(uint64 idPledge, uint amount) public { function withdraw(uint64 idPledge, uint amount) public {
idPledge = normalizePledge(idPledge); // Updates pledge info Pledges.Pledge memory p = normalizePledge(idPledge); // Updates pledge info
Pledges.Pledge memory p = findPledge(idPledge); // = findPledge(idPledge);
require(p.pledgeState == Pledges.PledgeState.Pledged); require(p.pledgeState == Pledges.PledgeState.Pledged);
checkAdminOwner(p.owner); checkAdminOwner(p.owner);
@ -289,7 +288,7 @@ contract LiquidPledging is LiquidPledgingBase {
Pledges.PledgeState.Pledged Pledges.PledgeState.Pledged
); );
oldPledge = normalizePledge(oldPledge); oldPledge = _normalizePledge(oldPledge);
doTransfer(p, oldPledge, amount); doTransfer(p, oldPledge, amount);
} }
@ -310,9 +309,10 @@ contract LiquidPledging is LiquidPledgingBase {
/// `oldPledge` /// `oldPledge`
function cancelPledge(uint64 idPledge, uint amount) public { function cancelPledge(uint64 idPledge, uint amount) public {
//TODO fetch idPledge? OR return Pledge from this call? //TODO fetch idPledge? OR return Pledge from this call?
idPledge = normalizePledge(idPledge); // idPledge = normalizePledge(idPledge);
Pledges.Pledge memory p = findPledge(idPledge); // Pledges.Pledge memory p = findPledge(idPledge);
Pledges.Pledge memory p = normalizePledge(idPledge);
require(p.oldPledge != 0); require(p.oldPledge != 0);
checkAdminOwner(p.owner); checkAdminOwner(p.owner);
@ -604,12 +604,12 @@ contract LiquidPledging is LiquidPledgingBase {
/// plugins, which also need to be predicted by the UI /// plugins, which also need to be predicted by the UI
/// @param idPledge This is the id of the pledge that will be normalized /// @param idPledge This is the id of the pledge that will be normalized
/// @return The normalized Pledge! /// @return The normalized Pledge!
function normalizePledge(uint64 idPledge) public returns(uint64) { function normalizePledge(uint64 idPledge) public returns(Pledges.Pledge) {
Pledges.Pledge memory p = findPledge(idPledge); Pledges.Pledge memory p = findPledge(idPledge);
return uint64(normalizePledge(p).id); return _normalizePledge(p);
} }
function normalizePledge(Pledges.Pledge p) internal returns(Pledges.Pledge) { function _normalizePledge(Pledges.Pledge p) internal returns(Pledges.Pledge) {
// Check to make sure this pledge hasn't already been used // Check to make sure this pledge hasn't already been used
// or is in the process of being used // or is in the process of being used

View File

@ -97,7 +97,7 @@ contract LiquidPledgingBase is LiquidPledgingStorage, PledgeAdmins, Pledges, Esc
/// plugin contract for a specific Admin /// plugin contract for a specific Admin
/// @param idAdmin The id of the admin being checked /// @param idAdmin The id of the admin being checked
function checkAdminOwner(uint idAdmin) internal constant { function checkAdminOwner(uint idAdmin) internal constant {
require(msg.sender == getAdminPlugin(idAdmin) || msg.sender == getAdminAddr(idAdmin)); require(msg.sender == getAdminAddr(idAdmin) || msg.sender == getAdminPlugin(idAdmin));
} }
/// @notice A getter to find the longest commitTime out of the owner and all /// @notice A getter to find the longest commitTime out of the owner and all

View File

@ -1,6 +1,6 @@
/* eslint-env mocha */ /* eslint-env mocha */
/* eslint-disable no-await-in-loop */ /* eslint-disable no-await-in-loop */
const TestRPC = require("ganache-cli"); const TestRPC = require('ganache-cli');
const Web3 = require('web3'); const Web3 = require('web3');
const chai = require('chai'); const chai = require('chai');
const liquidpledging = require('../index.js'); const liquidpledging = require('../index.js');
@ -341,26 +341,11 @@ describe('LiquidPledging test', function () {
it('should throw if projectLevel > 20', async () => { it('should throw if projectLevel > 20', async () => {
let nAdmins = await liquidPledging.numberOfPledgeAdmins(); let nAdmins = await liquidPledging.numberOfPledgeAdmins();
await liquidPledging.addProject('ProjectLevel1', '', adminProject1, 0, 86400, 0, { from: adminProject1 }); await liquidPledging.addProject('ProjectLevel0', '', adminProject1, 0, 86400, 0, { from: adminProject1 });
await liquidPledging.addProject('ProjectLevel2', '', adminProject1, ++nAdmins, 86400, 0, { from: adminProject1 });
await liquidPledging.addProject('ProjectLevel3', '', adminProject1, ++nAdmins, 86400, 0, { from: adminProject1 }); for (let i = 2; i <= 20; i++) {
await liquidPledging.addProject('ProjectLevel4', '', adminProject1, ++nAdmins, 86400, 0, { from: adminProject1 }); await liquidPledging.addProject(`ProjectLevel${i}`, '', adminProject1, ++nAdmins, 86400, 0, { from: adminProject1 });
await liquidPledging.addProject('ProjectLevel5', '', adminProject1, ++nAdmins, 86400, 0, { from: adminProject1 }); }
await liquidPledging.addProject('ProjectLevel6', '', adminProject1, ++nAdmins, 86400, 0, { from: adminProject1 });
await liquidPledging.addProject('ProjectLevel7', '', adminProject1, ++nAdmins, 86400, 0, { from: adminProject1 });
await liquidPledging.addProject('ProjectLevel8', '', adminProject1, ++nAdmins, 86400, 0, { from: adminProject1 });
await liquidPledging.addProject('ProjectLevel9', '', adminProject1, ++nAdmins, 86400, 0, { from: adminProject1 });
await liquidPledging.addProject('ProjectLevel10', '', adminProject1, ++nAdmins, 86400, 0, { from: adminProject1 });
await liquidPledging.addProject('ProjectLevel11', '', adminProject1, ++nAdmins, 86400, 0, { from: adminProject1 });
await liquidPledging.addProject('ProjectLevel12', '', adminProject1, ++nAdmins, 86400, 0, { from: adminProject1 });
await liquidPledging.addProject('ProjectLevel13', '', adminProject1, ++nAdmins, 86400, 0, { from: adminProject1 });
await liquidPledging.addProject('ProjectLevel14', '', adminProject1, ++nAdmins, 86400, 0, { from: adminProject1 });
await liquidPledging.addProject('ProjectLevel15', '', adminProject1, ++nAdmins, 86400, 0, { from: adminProject1 });
await liquidPledging.addProject('ProjectLevel16', '', adminProject1, ++nAdmins, 86400, 0, { from: adminProject1 });
await liquidPledging.addProject('ProjectLevel17', '', adminProject1, ++nAdmins, 86400, 0, { from: adminProject1 });
await liquidPledging.addProject('ProjectLevel18', '', adminProject1, ++nAdmins, 86400, 0, { from: adminProject1 });
await liquidPledging.addProject('ProjectLevel19', '', adminProject1, ++nAdmins, 86400, 0, { from: adminProject1 });
await liquidPledging.addProject('ProjectLevel20', '', adminProject1, ++nAdmins, 86400, 0, { from: adminProject1 });
assertFail( assertFail(
liquidPledging.addProject('ProjectLevel21', '', adminProject1, ++nAdmins, 86400, 0, { from: adminProject1, gas: 4000000 }) liquidPledging.addProject('ProjectLevel21', '', adminProject1, ++nAdmins, 86400, 0, { from: adminProject1, gas: 4000000 })