parent
3c19b0d36e
commit
e9b97b6218
@ -1,82 +0,0 @@
|
||||
pragma solidity ^0.5.1;
|
||||
|
||||
import "./SafeMath.sol";
|
||||
|
||||
library MinPriorityQueue {
|
||||
using SafeMath for uint;
|
||||
|
||||
function insert(uint[] storage self, uint i) internal {
|
||||
self.push(i);
|
||||
_percUp(self);
|
||||
}
|
||||
|
||||
function delMin(uint[] storage self) internal returns (uint) {
|
||||
uint min = self[0];
|
||||
|
||||
// replace last element with root
|
||||
self[0] = self[self.length - 1];
|
||||
self.pop();
|
||||
|
||||
_percDown(self);
|
||||
|
||||
return min;
|
||||
}
|
||||
|
||||
function getMin(uint[] storage self) internal view returns (uint) {
|
||||
return self[0];
|
||||
}
|
||||
|
||||
function _getMinIndex(uint[] storage self, uint i) private view returns (uint) {
|
||||
uint minIndex = i;
|
||||
uint leftIndex = i.mul(2).add(1);
|
||||
uint rightIndex = i.mul(2).add(2);
|
||||
|
||||
// NOTE: choose left index if left value < min and left value == right value
|
||||
if (leftIndex < self.length && self[leftIndex] < self[minIndex]) {
|
||||
minIndex = leftIndex;
|
||||
}
|
||||
if (rightIndex < self.length && self[rightIndex] < self[minIndex]) {
|
||||
minIndex = rightIndex;
|
||||
}
|
||||
|
||||
return minIndex;
|
||||
}
|
||||
|
||||
function _percUp(uint[] storage self) private {
|
||||
uint i = self.length - 1;
|
||||
|
||||
while (i > 0) {
|
||||
uint parentIndex = (i - 1) / 2;
|
||||
uint parent = self[parentIndex];
|
||||
uint child = self[i];
|
||||
|
||||
if (child >= parent) {
|
||||
return;
|
||||
}
|
||||
|
||||
self[parentIndex] = child;
|
||||
self[i] = parent;
|
||||
|
||||
i = parentIndex;
|
||||
}
|
||||
}
|
||||
|
||||
function _percDown(uint[] storage self) private {
|
||||
uint i = 0;
|
||||
|
||||
while (i < self.length) {
|
||||
uint parent = self[i];
|
||||
uint minIndex = _getMinIndex(self, i);
|
||||
uint min = self[minIndex];
|
||||
|
||||
if (parent <= min) {
|
||||
return;
|
||||
}
|
||||
|
||||
self[i] = min;
|
||||
self[minIndex] = parent;
|
||||
|
||||
i = minIndex;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
pragma solidity ^0.5.1;
|
||||
|
||||
import "./MinPriorityQueue.sol";
|
||||
|
||||
contract MinPriorityQueueTest {
|
||||
using MinPriorityQueue for uint[];
|
||||
|
||||
uint[] public heap;
|
||||
|
||||
function insert(uint256 k) public {
|
||||
heap.insert(k);
|
||||
}
|
||||
|
||||
function delMin() public {
|
||||
heap.delMin();
|
||||
}
|
||||
|
||||
function length() public view returns (uint256) {
|
||||
return heap.length;
|
||||
}
|
||||
|
||||
function getMin() public view returns (uint256) {
|
||||
require(heap.length > 0);
|
||||
return heap.getMin();
|
||||
}
|
||||
|
||||
function test() public returns (uint) {
|
||||
insert(3);
|
||||
insert(1);
|
||||
insert(5);
|
||||
insert(4);
|
||||
insert(2);
|
||||
|
||||
return getMin();
|
||||
}
|
||||
}
|
@ -1,106 +0,0 @@
|
||||
pragma solidity ^0.7;
|
||||
|
||||
/*
|
||||
- minimal proxy contract (deploy)
|
||||
|
||||
- Why is it cheap to deploy contract?
|
||||
- Why is constructor not called? deploys a contract that only calls delegatecall
|
||||
- Why is the original contract not affected? uses delegatecall
|
||||
|
||||
- delegatecall
|
||||
- minimal proxy contract (interaction)
|
||||
- Why is it cheap to deploy contract? there is minimal code
|
||||
- Why is the original contract not affected? uses delegatecall
|
||||
|
||||
- Why is constructor not called? deploys a simple contract that fowards all calls using delegatecall
|
||||
- vyper create_forwarder_to
|
||||
- pseudo code (notice constructor of master copy is not called)
|
||||
- actual code
|
||||
|
||||
3d602d80600a3d3981f3363d3d373d3d3d363d73bebebebebebebebebebebebebebebebebebebebe5af43d82803e903d91602b57fd5bf3
|
||||
|
||||
- bytecode
|
||||
- 2 parts (
|
||||
runtime code - delegate call
|
||||
creation code - return contract to delegate call
|
||||
)
|
||||
- creation code vs runtime code
|
||||
- clone factory
|
||||
- mstore diagram
|
||||
*/
|
||||
|
||||
contract PseudoMinimalProxy {
|
||||
address masterCopy;
|
||||
|
||||
constructor(address _masterCopy) {
|
||||
// notice that constructor of master copy is not called
|
||||
masterCopy = _masterCopy;
|
||||
}
|
||||
|
||||
function forward() external returns (bytes memory) {
|
||||
(bool success, bytes memory data) = masterCopy.delegatecall(msg.data);
|
||||
require(success);
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
contract MinimalProxy {
|
||||
function clone(address target) external returns (address result) {
|
||||
// convert address to 20 bytes
|
||||
bytes20 targetBytes = bytes20(target);
|
||||
|
||||
// actual code //
|
||||
// 3d602d80600a3d3981f3363d3d373d3d3d363d73bebebebebebebebebebebebebebebebebebebebe5af43d82803e903d91602b57fd5bf3
|
||||
|
||||
// creation code //
|
||||
// copy runtime code into memory and return it
|
||||
// 3d602d80600a3d3981f3
|
||||
|
||||
// runtime code //
|
||||
// code to delegatecall to address
|
||||
// 363d3d373d3d3d363d73 address 5af43d82803e903d91602b57fd5bf3
|
||||
|
||||
assembly {
|
||||
/*
|
||||
reads the 32 bytes of memory starting at pointer stored in 0x40
|
||||
|
||||
In solidity, the 0x40 slot in memory is special: it contains the "free memory pointer"
|
||||
which points to the end of the currently allocated memory.
|
||||
*/
|
||||
let clone := mload(0x40)
|
||||
// store 32 bytes to memory starting at "clone"
|
||||
mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
|
||||
|
||||
/*
|
||||
| 20 bytes |
|
||||
0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000
|
||||
^
|
||||
pointer
|
||||
*/
|
||||
// store 32 bytes to memory starting at "clone" + 20 bytes
|
||||
// 0x14 = 20
|
||||
mstore(add(clone, 0x14), targetBytes)
|
||||
|
||||
/*
|
||||
| 20 bytes | 20 bytes |
|
||||
0x3d602d80600a3d3981f3363d3d373d3d3d363d73bebebebebebebebebebebebebebebebebebebebe
|
||||
^
|
||||
pointer
|
||||
*/
|
||||
// store 32 bytes to memory starting at "clone" + 40 bytes
|
||||
// 0x28 = 40
|
||||
mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
|
||||
|
||||
/*
|
||||
| 20 bytes | 20 bytes | 15 bytes |
|
||||
0x3d602d80600a3d3981f3363d3d373d3d3d363d73bebebebebebebebebebebebebebebebebebebebe5af43d82803e903d91602b57fd5bf3
|
||||
*/
|
||||
// create new contract
|
||||
// send 0 Ether
|
||||
// code starts at pointer stored in "clone"
|
||||
// code size 0x37 (55 bytes)
|
||||
result := create(0, clone, 0x37)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in new issue