Skip to content

Commit f7d29f4

Browse files
authored
🦜 Legacy impl
🦜 Legacy impl
2 parents 2aba2b9 + ef16c6e commit f7d29f4

File tree

4 files changed

+241
-2
lines changed

4 files changed

+241
-2
lines changed

Diff for: ‎deployments.json

+6-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
"impls": "0x331Cf6E3E59B18a8bc776A0F652aF9E2b42781c5",
1616
"account": "0xFa923AA6b4DF5bea456DF37FA044B37F0FDDCdb4",
1717
"defaultImpl": "0x684BBb31eb2F7891523fAfc2CC5A0fB0a45C4DC4",
18-
"mainImpl": "0x4c587a067636fCEF2B6B171535B545845067843a"
18+
"mainImpl": "0x4c587a067636fCEF2B6B171535B545845067843a",
19+
"legacyConnectors": "0xbB0A24A685aEC75926E9c51b7DCF29b69f7e2A33",
20+
"legacyImpl": "0x12a4CC40a8F89E40F8C849c2F89741D5C9590a14"
1921
},
2022
"optimism-goerli": {
2123
"index": "0xC7a069dD24178DF00914d49Bf674A40A1420CF01",
@@ -42,6 +44,8 @@
4244
"impls": "0x6c4c4971936F091Ba351a4e9B621FcCDC03455e4",
4345
"account": "0xA8BBBf760A0fFc28A5B1fF6AFe86280061445EE9",
4446
"defaultImpl": "0xa4c1B0B3a8B97F9951e1Bf156E9Fe19c1a17c3Db",
45-
"mainImpl": "0x3EEBDDC12D6dd5fc0603998384A6EEaD1B126045"
47+
"mainImpl": "0x3EEBDDC12D6dd5fc0603998384A6EEaD1B126045",
48+
"legacyConnectors": "0x8eBD88707b3D71f511b714aF696fAE44b4D3d3A8",
49+
"legacyImpl": "0x1796B87e76Ca876aC06cE4F96C6b4cAda1d12f2E"
4650
}
4751
}

Diff for: ‎script/DeployLegacy.s.sol

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.9;
3+
4+
import {Script} from "forge-std/Script.sol";
5+
import {console2} from "forge-std/console2.sol";
6+
7+
import {LegacyImplementation} from "../src/accounts/LegacyImpl.sol";
8+
import {PolyLegacyConnectors} from "../src/registry/LegacyConnectors.sol";
9+
import {PolyImplementations} from "../src/registry/Implementations.sol";
10+
11+
contract DeployLegacy is Script {
12+
function run() external {
13+
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
14+
vm.startBroadcast(deployerPrivateKey);
15+
16+
address polyIndex = 0x2d4937ED79D434290c4baeA6d390b78c0bf907d8;
17+
PolyImplementations impls = PolyImplementations(0x331Cf6E3E59B18a8bc776A0F652aF9E2b42781c5);
18+
19+
PolyLegacyConnectors legacyConnectors = new PolyLegacyConnectors(polyIndex);
20+
LegacyImplementation legacyImpl = new LegacyImplementation(polyIndex, address(legacyConnectors));
21+
22+
bytes4[] memory selectors = new bytes4[](1);
23+
selectors[0] = LegacyImplementation.cast.selector;
24+
25+
address[] memory connectorsToAdd = new address[](1);
26+
connectorsToAdd[0] = 0x3ba6A43ebf48520ea099ab07b411974f8494B390; // Base Synthetix Perp
27+
28+
impls.addImplementation(address(legacyImpl), selectors);
29+
legacyConnectors.addConnectors(connectorsToAdd);
30+
31+
vm.stopBroadcast();
32+
}
33+
}

Diff for: ‎src/accounts/LegacyImpl.sol

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.9;
3+
4+
import {Variables} from "./Variables.sol";
5+
6+
/**
7+
* @title FxWallet.
8+
* @dev fx Wallet.
9+
*/
10+
interface ConnectorsInterface {
11+
function isConnectors(address[] calldata connectorNames) external view returns (bool);
12+
}
13+
14+
contract Constants is Variables {
15+
// polyIndex Address.
16+
address internal immutable polyIndex;
17+
// Connectors Address.
18+
address public immutable connectors;
19+
20+
constructor(address _polyIndex, address _connectors) {
21+
connectors = _connectors;
22+
polyIndex = _polyIndex;
23+
}
24+
}
25+
26+
contract LegacyImplementation is Constants {
27+
constructor(address _polyIndex, address _connectors) Constants(_polyIndex, _connectors) {}
28+
29+
function decodeEvent(bytes memory response)
30+
internal
31+
pure
32+
returns (string memory _eventCode, bytes memory _eventParams)
33+
{
34+
if (response.length > 0) {
35+
(_eventCode, _eventParams) = abi.decode(response, (string, bytes));
36+
}
37+
}
38+
39+
event LogCast(
40+
address indexed origin,
41+
address indexed sender,
42+
uint256 value,
43+
address[] targets,
44+
string[] eventNames,
45+
bytes[] eventParams
46+
);
47+
48+
receive() external payable {}
49+
50+
/**
51+
* @dev Delegate the calls to Connector.
52+
* @param _target Connector address
53+
* @param _data CallData of function.
54+
*/
55+
function spell(address _target, bytes memory _data) internal returns (bytes memory response) {
56+
require(_target != address(0), "target-invalid");
57+
assembly {
58+
let succeeded := delegatecall(gas(), _target, add(_data, 0x20), mload(_data), 0, 0)
59+
let size := returndatasize()
60+
61+
response := mload(0x40)
62+
mstore(0x40, add(response, and(add(add(size, 0x20), 0x1f), not(0x1f))))
63+
mstore(response, size)
64+
returndatacopy(add(response, 0x20), 0, size)
65+
66+
switch iszero(succeeded)
67+
case 1 {
68+
// throw if delegatecall failed
69+
returndatacopy(0x00, 0x00, size)
70+
revert(0x00, size)
71+
}
72+
}
73+
}
74+
75+
/**
76+
* @dev This is the main function, Where all the different functions are called
77+
* from Smart Account.
78+
* @param _targets Array of Connector address.
79+
* @param _datas Array of Calldata.
80+
*/
81+
function cast(address[] calldata _targets, bytes[] calldata _datas, address _origin)
82+
external
83+
payable
84+
returns (
85+
bytes32 // Dummy return to fix polyIndex buildWithCast function
86+
)
87+
{
88+
uint256 _length = _targets.length;
89+
require(_auth[msg.sender] || msg.sender == polyIndex, "1: permission-denied");
90+
require(_length != 0, "1: length-invalid");
91+
require(_length == _datas.length, "1: array-length-invalid");
92+
93+
string[] memory eventNames = new string[](_length);
94+
bytes[] memory eventParams = new bytes[](_length);
95+
96+
bool isOk = ConnectorsInterface(connectors).isConnectors(_targets);
97+
98+
require(isOk, "1: not-connector");
99+
100+
for (uint256 i = 0; i < _length; i++) {
101+
bytes memory response = spell(_targets[i], _datas[i]);
102+
(eventNames[i], eventParams[i]) = decodeEvent(response);
103+
}
104+
105+
emit LogCast(_origin, msg.sender, msg.value, _targets, eventNames, eventParams);
106+
}
107+
}

Diff for: ‎src/registry/LegacyConnectors.sol

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.9;
3+
4+
/**
5+
* @title PolyConnectors
6+
* @dev Registry for Connectors.
7+
*/
8+
interface IndexInterface {
9+
function master() external view returns (address);
10+
}
11+
12+
interface ConnectorInterface {
13+
function name() external view returns (string memory);
14+
}
15+
16+
contract Controllers {
17+
event LogController(address indexed addr, bool indexed isChief);
18+
19+
// PolyIndex Address.
20+
address public immutable polyIndex;
21+
22+
constructor(address _polyIndex) {
23+
polyIndex = _polyIndex;
24+
}
25+
26+
// Enabled Chief(Address of Chief => bool).
27+
mapping(address => bool) public chief;
28+
// Enabled Connectors(Connector name => address).
29+
mapping(address => bool) public connectors;
30+
31+
/**
32+
* @dev Throws if the sender not is Master Address from PolyIndex
33+
* or Enabled Chief.
34+
*/
35+
modifier isChief() {
36+
require(chief[msg.sender] || msg.sender == IndexInterface(polyIndex).master(), "not-an-chief");
37+
_;
38+
}
39+
40+
/**
41+
* @dev Toggle a Chief. Enable if disable & vice versa
42+
* @param _chiefAddress Chief Address.
43+
*/
44+
function toggleChief(address _chiefAddress) external {
45+
require(msg.sender == IndexInterface(polyIndex).master(), "toggleChief: not-master");
46+
chief[_chiefAddress] = !chief[_chiefAddress];
47+
emit LogController(_chiefAddress, chief[_chiefAddress]);
48+
}
49+
}
50+
51+
contract PolyLegacyConnectors is Controllers {
52+
event LogConnectorAdded(address indexed connector);
53+
event LogConnectorRemoved(address indexed connector);
54+
55+
constructor(address _polyIndex) Controllers(_polyIndex) {}
56+
57+
/**
58+
* @dev Add Connectors
59+
* @param _connectors Array of Connector Address.
60+
*/
61+
function addConnectors(address[] calldata _connectors) external isChief {
62+
for (uint256 i = 0; i < _connectors.length; i++) {
63+
require(!connectors[_connectors[i]], "addConnectors: _connector added already");
64+
require(_connectors[i] != address(0), "addConnectors: _connectors address not vaild");
65+
ConnectorInterface(_connectors[i]).name(); // Checking if connector has function name()
66+
connectors[_connectors[i]] = true;
67+
emit LogConnectorAdded(_connectors[i]);
68+
}
69+
}
70+
71+
/**
72+
* @dev Remove Connectors
73+
* @param _connectors Array of Connector Addresses.
74+
*/
75+
function removeConnectors(address[] calldata _connectors) external isChief {
76+
for (uint256 i = 0; i < _connectors.length; i++) {
77+
require(connectors[_connectors[i]], "removeConnectors: _connector not added to remove");
78+
emit LogConnectorRemoved(_connectors[i]);
79+
delete connectors[_connectors[i]];
80+
}
81+
}
82+
83+
/**
84+
* @dev Check if Connector addresses are enabled.
85+
* @param _connectors Array of Connector Addresses.
86+
*/
87+
function isConnectors(address[] calldata _connectors) external view returns (bool isOk) {
88+
isOk = true;
89+
for (uint256 i = 0; i < _connectors.length; i++) {
90+
if (!connectors[_connectors[i]]) {
91+
return false;
92+
}
93+
}
94+
}
95+
}

0 commit comments

Comments
 (0)