forked from cerc-io/laconicd-deprecated
tests: reorganize packages (#7)
* tests: reorganize testing packages * gitignore and minor changes
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
pragma solidity 0.4.24;
|
||||
|
||||
import "./IsContract.sol";
|
||||
import "./ERCProxy.sol";
|
||||
|
||||
|
||||
contract DelegateProxy is ERCProxy, IsContract {
|
||||
uint256 internal constant FWD_GAS_LIMIT = 10000;
|
||||
|
||||
/**
|
||||
* @dev Performs a delegatecall and returns whatever the delegatecall returned (entire context execution will return!)
|
||||
* @param _dst Destination address to perform the delegatecall
|
||||
* @param _calldata Calldata for the delegatecall
|
||||
*/
|
||||
function delegatedFwd(address _dst, bytes _calldata) internal {
|
||||
require(isContract(_dst));
|
||||
uint256 fwdGasLimit = FWD_GAS_LIMIT;
|
||||
|
||||
assembly {
|
||||
let result := delegatecall(sub(gas, fwdGasLimit), _dst, add(_calldata, 0x20), mload(_calldata), 0, 0)
|
||||
let size := returndatasize
|
||||
let ptr := mload(0x40)
|
||||
returndatacopy(ptr, 0, size)
|
||||
|
||||
// revert instead of invalid() bc if the underlying call failed with invalid() it already wasted gas.
|
||||
// if the call returned error data, forward it
|
||||
switch result case 0 { revert(ptr, size) }
|
||||
default { return(ptr, size) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
pragma solidity 0.4.24;
|
||||
|
||||
import "./DelegateProxy.sol";
|
||||
import "./DepositableStorage.sol";
|
||||
|
||||
|
||||
contract DepositableDelegateProxy is DepositableStorage, DelegateProxy {
|
||||
event ProxyDeposit(address sender, uint256 value);
|
||||
|
||||
function () external payable {
|
||||
uint256 forwardGasThreshold = FWD_GAS_LIMIT;
|
||||
bytes32 isDepositablePosition = DEPOSITABLE_POSITION;
|
||||
|
||||
// Optimized assembly implementation to prevent EIP-1884 from breaking deposits, reference code in Solidity:
|
||||
// https://github.com/aragon/aragonOS/blob/v4.2.1/contracts/common/DepositableDelegateProxy.sol#L10-L20
|
||||
assembly {
|
||||
// Continue only if the gas left is lower than the threshold for forwarding to the implementation code,
|
||||
// otherwise continue outside of the assembly block.
|
||||
if lt(gas, forwardGasThreshold) {
|
||||
// Only accept the deposit and emit an event if all of the following are true:
|
||||
// the proxy accepts deposits (isDepositable), msg.data.length == 0, and msg.value > 0
|
||||
if and(and(sload(isDepositablePosition), iszero(calldatasize)), gt(callvalue, 0)) {
|
||||
// Equivalent Solidity code for emitting the event:
|
||||
// emit ProxyDeposit(msg.sender, msg.value);
|
||||
|
||||
let logData := mload(0x40) // free memory pointer
|
||||
mstore(logData, caller) // add 'msg.sender' to the log data (first event param)
|
||||
mstore(add(logData, 0x20), callvalue) // add 'msg.value' to the log data (second event param)
|
||||
|
||||
// Emit an event with one topic to identify the event: keccak256('ProxyDeposit(address,uint256)') = 0x15ee...dee1
|
||||
log1(logData, 0x40, 0x15eeaa57c7bd188c1388020bcadc2c436ec60d647d36ef5b9eb3c742217ddee1)
|
||||
|
||||
stop() // Stop. Exits execution context
|
||||
}
|
||||
|
||||
// If any of above checks failed, revert the execution (if ETH was sent, it is returned to the sender)
|
||||
revert(0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
address target = implementation();
|
||||
delegatedFwd(target, msg.data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
pragma solidity 0.4.24;
|
||||
|
||||
import "./UnstructuredStorage.sol";
|
||||
|
||||
|
||||
contract DepositableStorage {
|
||||
using UnstructuredStorage for bytes32;
|
||||
|
||||
// keccak256("aragonOS.depositableStorage.depositable")
|
||||
bytes32 internal constant DEPOSITABLE_POSITION = 0x665fd576fbbe6f247aff98f5c94a561e3f71ec2d3c988d56f12d342396c50cea;
|
||||
|
||||
function isDepositable() public view returns (bool) {
|
||||
return DEPOSITABLE_POSITION.getStorageBool();
|
||||
}
|
||||
|
||||
function setDepositable(bool _depositable) internal {
|
||||
DEPOSITABLE_POSITION.setStorageBool(_depositable);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
contract ERCProxy {
|
||||
uint256 internal constant FORWARDING = 1;
|
||||
uint256 internal constant UPGRADEABLE = 2;
|
||||
|
||||
function proxyType() public pure returns (uint256 proxyTypeId);
|
||||
function implementation() public view returns (address codeAddr);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
contract IsContract {
|
||||
/*
|
||||
* NOTE: this should NEVER be used for authentication
|
||||
* (see pitfalls: https://github.com/fergarrui/ethereum-security/tree/master/contracts/extcodesize).
|
||||
*
|
||||
* This is only intended to be used as a sanity check that an address is actually a contract,
|
||||
* RATHER THAN an address not being a contract.
|
||||
*/
|
||||
function isContract(address _target) internal view returns (bool) {
|
||||
if (_target == address(0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint256 size;
|
||||
assembly { size := extcodesize(_target) }
|
||||
return size > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
library UnstructuredStorage {
|
||||
function getStorageBool(bytes32 position) internal view returns (bool data) {
|
||||
assembly { data := sload(position) }
|
||||
}
|
||||
|
||||
function getStorageAddress(bytes32 position) internal view returns (address data) {
|
||||
assembly { data := sload(position) }
|
||||
}
|
||||
|
||||
function getStorageBytes32(bytes32 position) internal view returns (bytes32 data) {
|
||||
assembly { data := sload(position) }
|
||||
}
|
||||
|
||||
function getStorageUint256(bytes32 position) internal view returns (uint256 data) {
|
||||
assembly { data := sload(position) }
|
||||
}
|
||||
|
||||
function setStorageBool(bytes32 position, bool data) internal {
|
||||
assembly { sstore(position, data) }
|
||||
}
|
||||
|
||||
function setStorageAddress(bytes32 position, address data) internal {
|
||||
assembly { sstore(position, data) }
|
||||
}
|
||||
|
||||
function setStorageBytes32(bytes32 position, bytes32 data) internal {
|
||||
assembly { sstore(position, data) }
|
||||
}
|
||||
|
||||
function setStorageUint256(bytes32 position, uint256 data) internal {
|
||||
assembly { sstore(position, data) }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
pragma solidity 0.4.24;
|
||||
|
||||
import "../DepositableDelegateProxy.sol";
|
||||
|
||||
|
||||
contract DepositableDelegateProxyMock is DepositableDelegateProxy {
|
||||
address private implementationMock;
|
||||
|
||||
function enableDepositsOnMock() external {
|
||||
setDepositable(true);
|
||||
}
|
||||
|
||||
function setImplementationOnMock(address _implementationMock) external {
|
||||
implementationMock = _implementationMock;
|
||||
}
|
||||
|
||||
function implementation() public view returns (address) {
|
||||
return implementationMock;
|
||||
}
|
||||
|
||||
function proxyType() public pure returns (uint256 proxyTypeId) {
|
||||
return UPGRADEABLE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
pragma solidity 0.4.24;
|
||||
|
||||
|
||||
contract EthSender {
|
||||
function sendEth(address to) external payable {
|
||||
to.transfer(msg.value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity >=0.4.22 <0.8.0;
|
||||
|
||||
contract Migrations {
|
||||
address public owner = msg.sender;
|
||||
uint public last_completed_migration;
|
||||
|
||||
modifier restricted() {
|
||||
require(
|
||||
msg.sender == owner,
|
||||
"This function is restricted to the contract's owner"
|
||||
);
|
||||
_;
|
||||
}
|
||||
|
||||
function setCompleted(uint completed) public restricted {
|
||||
last_completed_migration = completed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
pragma solidity 0.4.24;
|
||||
|
||||
contract ProxyTargetWithoutFallback {
|
||||
event Pong();
|
||||
|
||||
function ping() external {
|
||||
emit Pong();
|
||||
}
|
||||
}
|
||||
|
||||
contract ProxyTargetWithFallback is ProxyTargetWithoutFallback {
|
||||
event ReceivedEth();
|
||||
|
||||
function () external payable {
|
||||
emit ReceivedEth();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user