diff --git a/test/Genesis.ts b/test/Genesis.ts new file mode 100644 index 0000000..6ba5d35 --- /dev/null +++ b/test/Genesis.ts @@ -0,0 +1,353 @@ +import { ethers } from 'hardhat'; +import { expect } from 'chai'; +import { loadFixture, time } from '@nomicfoundation/hardhat-network-helpers'; +import { beforeEach } from 'mocha'; +import { ConstantsManager, NodeDriver, NodeDriverAuth, SFC } from '../typechain-types'; + +// Test deployment and initialization of contracts by directly setting the bytecode +// This simulates start of a new network +describe('Genesis initialization', () => { + const fixture = async () => { + const [user, owner] = await ethers.getSigners(); + const initializer = '0xd1005eed00000000000000000000000000000000'; + const nodeDriverProxy = '0xd100a01e00000000000000000000000000000000'; + const nodeDriver = '0xd100a01e00000000000000000000000000000001'; + const nodeDriverAuthProxy = '0xd100ae0000000000000000000000000000000000'; + const nodeDriverAuth = '0xd100ae0000000000000000000000000000000001'; + const sfcProxy = '0xfc00face00000000000000000000000000000000'; + const sfc = '0xfc00face00000000000000000000000000000001'; + const evmWriter = '0xd100ec0000000000000000000000000000000000'; + const epoch = 10; + const totalSupply = 100_000_000; + + // set bytecodes + await ethers.provider.send('hardhat_setCode', [ + initializer, + '0x608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063c80e15131461002d575b5f5ffd5b61004061003b36600461079e565b610042565b005b60405163c0c53b8b60e01b81526001600160a01b0385811660048301528381166024830152828116604483015284169063c0c53b8b906064015f604051808303815f87803b158015610092575f5ffd5b505af11580156100a4573d5f5f3e3d5ffd5b505060405163c0c53b8b60e01b81526001600160a01b038881166004830152868116602483015284811660448301528716925063c0c53b8b91506064015f604051808303815f87803b1580156100f8575f5ffd5b505af115801561010a573d5f5f3e3d5ffd5b505050505f3060405161011c9061077a565b6001600160a01b039091168152602001604051809103905ff080158015610145573d5f5f3e3d5ffd5b5060405163866c4b1760e01b81526969e10de76676d080000060048201529091506001600160a01b0382169063866c4b17906024015f604051808303815f87803b158015610191575f5ffd5b505af11580156101a3573d5f5f3e3d5ffd5b50505050806001600160a01b03166381ffcdf16101c5670de0b6b3a764000090565b6101d090601061081d565b6040518263ffffffff1660e01b81526004016101ee91815260200190565b5f604051808303815f87803b158015610205575f5ffd5b505af1158015610217573d5f5f3e3d5ffd5b50505050806001600160a01b0316632ee71132606461023b670de0b6b3a764000090565b61024690600f61081d565b6102509190610846565b6040518263ffffffff1660e01b815260040161026e91815260200190565b5f604051808303815f87803b158015610285575f5ffd5b505af1158015610297573d5f5f3e3d5ffd5b50505050806001600160a01b0316632bb9fe8d60646102bb670de0b6b3a764000090565b6102c690601461081d565b6102d09190610846565b6040518263ffffffff1660e01b81526004016102ee91815260200190565b5f604051808303815f87803b158015610305575f5ffd5b505af1158015610317573d5f5f3e3d5ffd5b50505050806001600160a01b031663f8d5177e606461033b670de0b6b3a764000090565b61034690600a61081d565b6103509190610846565b6040518263ffffffff1660e01b815260040161036e91815260200190565b5f604051808303815f87803b158015610385575f5ffd5b505af1158015610397573d5f5f3e3d5ffd5b5050604051634783c5fd60e11b8152600360048201526001600160a01b0384169250638f078bfa91506024015f604051808303815f87803b1580156103da575f5ffd5b505af11580156103ec573d5f5f3e3d5ffd5b5050604051631154d9a960e21b815262093a8060048201526001600160a01b038416925063455366a491506024015f604051808303815f87803b158015610431575f5ffd5b505af1158015610443573d5f5f3e3d5ffd5b505060405163b6d9edd560e01b8152672508fab977b917d060048201526001600160a01b038416925063b6d9edd591506024015f604051808303815f87803b15801561048d575f5ffd5b505af115801561049f573d5f5f3e3d5ffd5b5050604051630c691d7760e31b81526206978060048201526001600160a01b0384169250636348ebb891506024015f604051808303815f87803b1580156104e4575f5ffd5b505af11580156104f6573d5f5f3e3d5ffd5b5050604051631742747360e11b81526103e860048201526001600160a01b0384169250632e84e8e691506024015f604051808303815f87803b15801561053a575f5ffd5b505af115801561054c573d5f5f3e3d5ffd5b5050604051634332686760e01b8152621e848060048201526001600160a01b0384169250634332686791506024015f604051808303815f87803b158015610591575f5ffd5b505af11580156105a3573d5f5f3e3d5ffd5b50506040516369fa46df60e11b8152610e1060048201526001600160a01b038416925063d3f48dbe91506024015f604051808303815f87803b1580156105e7575f5ffd5b505af11580156105f9573d5f5f3e3d5ffd5b50506040516312b6e2b960e11b8152606460048201526001600160a01b038416925063256dc57291506024015f604051808303815f87803b15801561063c575f5ffd5b505af115801561064e573d5f5f3e3d5ffd5b505060405163165e263960e01b81525f60048201526001600160a01b038416925063165e263991506024015f604051808303815f87803b158015610690575f5ffd5b505af11580156106a2573d5f5f3e3d5ffd5b505060405163f2fde38b60e01b81526001600160a01b0385811660048301528416925063f2fde38b91506024015f604051808303815f87803b1580156106e6575f5ffd5b505af11580156106f8573d5f5f3e3d5ffd5b5050604051633fbfd4df60e01b8152600481018b9052602481018a90526001600160a01b0388811660448301528481166064830152858116608483015289169250633fbfd4df915060a4015f604051808303815f87803b15801561075a575f5ffd5b505af115801561076c573d5f5f3e3d5ffd5b505050505050505050505050565b610c228061086683390190565b6001600160a01b038116811461079b575f5ffd5b50565b5f5f5f5f5f5f5f60e0888a0312156107b4575f5ffd5b873596506020880135955060408801356107cd81610787565b945060608801356107dd81610787565b935060808801356107ed81610787565b925060a08801356107fd81610787565b915060c088013561080d81610787565b8091505092959891949750929550565b808202811582820484141761084057634e487b7160e01b5f52601160045260245ffd5b92915050565b5f8261086057634e487b7160e01b5f52601260045260245ffd5b50049056fe6080604052348015600e575f5ffd5b50604051610c22380380610c22833981016040819052602b9160b4565b806001600160a01b038116605857604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b605f816065565b505060df565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f6020828403121560c3575f5ffd5b81516001600160a01b038116811460d8575f5ffd5b9392505050565b610b36806100ec5f395ff3fe608060405234801561000f575f5ffd5b50600436106101f1575f3560e01c8063715018a611610114578063a7786515116100a9578063c74dd62111610079578063c74dd621146103ff578063d3f48dbe14610408578063d9a7c1f91461041b578063f2fde38b14610424578063f8d5177e14610437575f5ffd5b8063a7786515146103d1578063b6d9edd5146103da578063b82b8427146103ed578063c5f530af146103f6575f5ffd5b8063866c4b17116100e4578063866c4b17146103925780638da5cb5b146103a55780638f078bfa146103b557806394c3e914146103c8575f5ffd5b8063715018a614610332578063754e92e31461033a57806375840fab1461034d57806381ffcdf11461037f575f5ffd5b80632ee711321161018a578063455366a41161015a578063455366a4146102fa5780635a68f01a1461030d5780636348ebb814610316578063650acd6614610329575f5ffd5b80632ee71132146102a65780633a3ef66c146102b95780633fa22548146102c257806343326867146102e7575f5ffd5b8063256dc572116101c5578063256dc572146102645780632bb9fe8d146102775780632c8c36a51461028a5780632e84e8e614610293575f5ffd5b8062cc7f83146101f5578063165e2639146102115780631c254337146102265780632265f2841461025b575b5f5ffd5b6101fe600a5481565b6040519081526020015b60405180910390f35b61022461021f366004610a2a565b61044a565b005b600d5461024290640100000000900467ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610208565b6101fe60025481565b610224610272366004610a58565b6104cb565b610224610285366004610a7b565b610541565b6101fe600c5481565b6102246102a1366004610a7b565b610581565b6102246102b4366004610a7b565b6105d4565b6101fe600b5481565b600d546102d29063ffffffff1681565b60405163ffffffff9091168152602001610208565b6102246102f5366004610a7b565b610614565b610224610308366004610a7b565b61066a565b6101fe60095481565b610224610324366004610a7b565b6106bf565b6101fe60065481565b610224610714565b610224610348366004610a92565b610727565b600d5461036790600160601b90046001600160a01b031681565b6040516001600160a01b039091168152602001610208565b61022461038d366004610a7b565b61075c565b6102246103a0366004610a7b565b6107c5565b5f546001600160a01b0316610367565b6102246103c3366004610a7b565b610829565b6101fe60055481565b6101fe60035481565b6102246103e8366004610a7b565b61087a565b6101fe60075481565b6101fe60015481565b6101fe60045481565b610224610416366004610a7b565b6108da565b6101fe60085481565b610224610432366004610a92565b61092d565b610224610445366004610a7b565b61096f565b6104526109af565b600a610467670de0b6b3a76400006009610ab8565b6104719190610ae1565b8167ffffffffffffffff16111561049b57604051632ad907fb60e01b815260040160405180910390fd5b600d805467ffffffffffffffff909216640100000000026bffffffffffffffff0000000019909216919091179055565b6104d36109af565b600a8163ffffffff1610156104fb57604051639a721da360e01b815260040160405180910390fd5b620156308163ffffffff16111561052557604051632ad907fb60e01b815260040160405180910390fd5b600d805463ffffffff191663ffffffff92909216919091179055565b6105496109af565b61055c6002670de0b6b3a7640000610ae1565b81111561057c57604051632ad907fb60e01b815260040160405180910390fd5b600455565b6105896109af565b60648110156105ab57604051639a721da360e01b815260040160405180910390fd5b620f42408111156105cf57604051632ad907fb60e01b815260040160405180910390fd5b600955565b6105dc6109af565b6105ef6002670de0b6b3a7640000610ae1565b81111561060f57604051632ad907fb60e01b815260040160405180910390fd5b600355565b61061c6109af565b620f424081101561064057604051639a721da360e01b815260040160405180910390fd5b631dcd650081111561066557604051632ad907fb60e01b815260040160405180910390fd5b600b55565b6106726109af565b6201518081101561069657604051639a721da360e01b815260040160405180910390fd5b62278d008111156106ba57604051632ad907fb60e01b815260040160405180910390fd5b600755565b6106c76109af565b620151808110156106eb57604051639a721da360e01b815260040160405180910390fd5b620d2f0081111561070f57604051632ad907fb60e01b815260040160405180910390fd5b600a55565b61071c6109af565b6107255f6109db565b565b61072f6109af565b600d80546001600160a01b03909216600160601b026bffffffffffffffffffffffff909216919091179055565b6107646109af565b670de0b6b3a764000081101561078d57604051639a721da360e01b815260040160405180910390fd5b6107a0670de0b6b3a7640000601f610ab8565b8111156107c057604051632ad907fb60e01b815260040160405180910390fd5b600255565b6107cd6109af565b69152d02c7e14af68000008110156107f857604051639a721da360e01b815260040160405180910390fd5b6a084595161401484a00000081111561082457604051632ad907fb60e01b815260040160405180910390fd5b600155565b6108316109af565b600281101561085357604051639a721da360e01b815260040160405180910390fd5b606481111561087557604051632ad907fb60e01b815260040160405180910390fd5b600655565b6108826109af565b6706f05b59d3b200008110156108ab57604051639a721da360e01b815260040160405180910390fd5b6801bc16d674ec8000008111156108d557604051632ad907fb60e01b815260040160405180910390fd5b600855565b6108e26109af565b606481101561090457604051639a721da360e01b815260040160405180910390fd5b620d2f0081111561092857604051632ad907fb60e01b815260040160405180910390fd5b600c55565b6109356109af565b6001600160a01b03811661096357604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b61096c816109db565b50565b6109776109af565b61098a6002670de0b6b3a7640000610ae1565b8111156109aa57604051632ad907fb60e01b815260040160405180910390fd5b600555565b5f546001600160a01b031633146107255760405163118cdaa760e01b815233600482015260240161095a565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f60208284031215610a3a575f5ffd5b813567ffffffffffffffff81168114610a51575f5ffd5b9392505050565b5f60208284031215610a68575f5ffd5b813563ffffffff81168114610a51575f5ffd5b5f60208284031215610a8b575f5ffd5b5035919050565b5f60208284031215610aa2575f5ffd5b81356001600160a01b0381168114610a51575f5ffd5b8082028115828204841417610adb57634e487b7160e01b5f52601160045260245ffd5b92915050565b5f82610afb57634e487b7160e01b5f52601260045260245ffd5b50049056fea26469706673582212209341b5c44574935d2b83f4151abacd32af50aab01d303d6a4b40cce43bf0a9d264736f6c634300081b0033a264697066735822122015847cf51f2c069911c9325a62448f6e4e9318d9f94b7f972f663a611c92ac5c64736f6c634300081b0033', + ]); + await ethers.provider.send('hardhat_setCode', [ + nodeDriverProxy, + '0x6080604052600a600c565b005b60186014601a565b6051565b565b6000604c7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b3660008037600080366000845af43d6000803e808015606f573d6000f35b3d6000fdfea2646970667358221220d0232cfa81216c3e4973e570f043b57ccb69ae4a81b8bc064338713721c87a9f64736f6c63430008140033', + ]); + await ethers.provider.send('hardhat_setCode', [ + nodeDriver, + '0x608060405260043610610131575f3560e01c80638da5cb5b116100a8578063c0c53b8b1161006d578063c0c53b8b1461035d578063d6a0c7af1461037c578063e08d7e661461039b578063e30443bc146103ba578063ebdf104c146103d9578063f2fde38b146103f8575f5ffd5b80638da5cb5b1461027d578063a4066fbe146102c3578063a8ab09ba146102e2578063ad3cb1cc14610301578063b9cc6b1c1461033e575f5ffd5b806339e503ab116100f957806339e503ab146101d25780634f1ef286146101f157806352d1902d14610204578063715018a61461022b57806376fed43a1461023f57806379bead381461025e575f5ffd5b806307690b2a146101355780630aeeca00146101565780631e702f8314610175578063242a6e3f14610194578063267ab446146101b3575b5f5ffd5b348015610140575f5ffd5b5061015461014f366004611129565b610417565b005b348015610161575f5ffd5b5061015461017036600461115a565b6104a8565b348015610180575f5ffd5b5061015461018f366004611171565b610509565b34801561019f575f5ffd5b506101546101ae3660046111d5565b61055f565b3480156101be575f5ffd5b506101546101cd36600461115a565b6105c8565b3480156101dd575f5ffd5b506101546101ec36600461121c565b610622565b6101546101ff366004611260565b6106ba565b34801561020f575f5ffd5b506102186106d9565b6040519081526020015b60405180910390f35b348015610236575f5ffd5b506101546106f4565b34801561024a575f5ffd5b50610154610259366004611321565b610707565b348015610269575f5ffd5b5061015461027836600461137d565b610791565b348015610288575f5ffd5b507f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546040516001600160a01b039091168152602001610222565b3480156102ce575f5ffd5b506101546102dd366004611171565b6107f4565b3480156102ed575f5ffd5b506101546102fc36600461121c565b61085c565b34801561030c575f5ffd5b50610331604051806040016040528060058152602001640352e302e360dc1b81525081565b60405161022291906113a5565b348015610349575f5ffd5b506101546103583660046113da565b6108ba565b348015610368575f5ffd5b50610154610377366004611418565b610921565b348015610387575f5ffd5b50610154610396366004611129565b610a66565b3480156103a6575f5ffd5b506101546103b5366004611498565b610aca565b3480156103c5575f5ffd5b506101546103d436600461137d565b610b1a565b3480156103e4575f5ffd5b506101546103f33660046114ca565b610b7d565b348015610403575f5ffd5b50610154610412366004611594565b610c10565b5f546001600160a01b0316331461044157604051630a31c3dd60e41b815260040160405180910390fd5b6001546040516303b4859560e11b81526001600160a01b0384811660048301528381166024830152909116906307690b2a906044015b5f604051808303815f87803b15801561048e575f5ffd5b505af11580156104a0573d5f5f3e3d5ffd5b505050505050565b5f546001600160a01b031633146104d257604051630a31c3dd60e41b815260040160405180910390fd5b6040518181527f0151256d62457b809bbc891b1f81c6dd0b9987552c70ce915b519750cd434dd1906020015b60405180910390a150565b331561052857604051630b9a4d6d60e31b815260040160405180910390fd5b5f54604051631e702f8360e01b815260048101849052602481018390526001600160a01b0390911690631e702f8390604401610477565b5f546001600160a01b0316331461058957604051630a31c3dd60e41b815260040160405180910390fd5b827f0f0ef1ab97439def0a9d2c6d9dc166207f1b13b99e62b442b2993d6153c63a6e83836040516105bb9291906115d5565b60405180910390a2505050565b5f546001600160a01b031633146105f257604051630a31c3dd60e41b815260040160405180910390fd5b6040518181527f2ccdfd47cf0c1f1069d949f1789bb79b2f12821f021634fc835af1de66ea2feb906020016104fe565b5f546001600160a01b0316331461064c57604051630a31c3dd60e41b815260040160405180910390fd5b6001546040516339e503ab60e01b81526001600160a01b0385811660048301526024820185905260448201849052909116906339e503ab906064015b5f604051808303815f87803b15801561069f575f5ffd5b505af11580156106b1573d5f5f3e3d5ffd5b50505050505050565b6106c2610c52565b6106cb82610cf6565b6106d58282610cfe565b5050565b5f6106e2610dbf565b505f5160206116f95f395f51905f5290565b6106fc610e08565b6107055f610e63565b565b331561072657604051630b9a4d6d60e31b815260040160405180910390fd5b5f54604051633b7f6a1d60e11b81526001600160a01b03909116906376fed43a9061075d90889088908890889088906004016115f0565b5f604051808303815f87803b158015610774575f5ffd5b505af1158015610786573d5f5f3e3d5ffd5b505050505050505050565b5f546001600160a01b031633146107bb57604051630a31c3dd60e41b815260040160405180910390fd5b600154604051630f37d5a760e31b81526001600160a01b03848116600483015260248201849052909116906379bead3890604401610477565b5f546001600160a01b0316331461081e57604051630a31c3dd60e41b815260040160405180910390fd5b817fb975807576e3b1461be7de07ebf7d20e4790ed802d7a0c4fdd0a1a13df72a9358260405161085091815260200190565b60405180910390a25050565b331561087b57604051630b9a4d6d60e31b815260040160405180910390fd5b5f5460405163545584dd60e11b81526001600160a01b03858116600483015260248201859052604482018490529091169063a8ab09ba90606401610688565b5f546001600160a01b031633146108e457604051630a31c3dd60e41b815260040160405180910390fd5b7f47d10eed096a44e3d0abc586c7e3a5d6cb5358cc90e7d437cd0627f7e765fb9982826040516109159291906115d5565b60405180910390a15050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f811580156109655750825b90505f826001600160401b031660011480156109805750303b155b90508115801561098e575080155b156109ac5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156109d657845460ff60401b1916600160401b1785555b6109df86610ed3565b6109e7610ee4565b5f80546001600160a01b03808b166001600160a01b03199283161790925560018054928a16929091169190911790558315610a5c57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b5f546001600160a01b03163314610a9057604051630a31c3dd60e41b815260040160405180910390fd5b60015460405163d6a0c7af60e01b81526001600160a01b03848116600483015283811660248301529091169063d6a0c7af90604401610477565b3315610ae957604051630b9a4d6d60e31b815260040160405180910390fd5b5f54604051637046bf3360e11b81526001600160a01b039091169063e08d7e66906104779085908590600401611659565b5f546001600160a01b03163314610b4457604051630a31c3dd60e41b815260040160405180910390fd5b6001546040516338c110ef60e21b81526001600160a01b038481166004830152602482018490529091169063e30443bc90604401610477565b3315610b9c57604051630b9a4d6d60e31b815260040160405180910390fd5b5f54604051633af7c41360e21b81526001600160a01b039091169063ebdf104c90610bd9908b908b908b908b908b908b908b908b9060040161166c565b5f604051808303815f87803b158015610bf0575f5ffd5b505af1158015610c02573d5f5f3e3d5ffd5b505050505050505050505050565b610c18610e08565b6001600160a01b038116610c4657604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b610c4f81610e63565b50565b306001600160a01b037f000000000000000000000000d100a01e00000000000000000000000000000001161480610cd857507f000000000000000000000000d100a01e000000000000000000000000000000016001600160a01b0316610ccc5f5160206116f95f395f51905f52546001600160a01b031690565b6001600160a01b031614155b156107055760405163703e46dd60e11b815260040160405180910390fd5b610c4f610e08565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610d58575060408051601f3d908101601f19168201909252610d55918101906116cb565b60015b610d8057604051634c9c8ce360e01b81526001600160a01b0383166004820152602401610c3d565b5f5160206116f95f395f51905f528114610db057604051632a87526960e21b815260048101829052602401610c3d565b610dba8383610eec565b505050565b306001600160a01b037f000000000000000000000000d100a01e0000000000000000000000000000000116146107055760405163703e46dd60e11b815260040160405180910390fd5b33610e3a7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b0316146107055760405163118cdaa760e01b8152336004820152602401610c3d565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b610edb610f41565b610c4f81610f8a565b610705610f41565b610ef582610f92565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a2805115610f3957610dba8282610ff5565b6106d5611067565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff1661070557604051631afcd79f60e31b815260040160405180910390fd5b610c18610f41565b806001600160a01b03163b5f03610fc757604051634c9c8ce360e01b81526001600160a01b0382166004820152602401610c3d565b5f5160206116f95f395f51905f5280546001600160a01b0319166001600160a01b0392909216919091179055565b60605f5f846001600160a01b03168460405161101191906116e2565b5f60405180830381855af49150503d805f8114611049576040519150601f19603f3d011682016040523d82523d5f602084013e61104e565b606091505b509150915061105e858383611086565b95945050505050565b34156107055760405163b398979f60e01b815260040160405180910390fd5b60608261109b57611096826110e5565b6110de565b81511580156110b257506001600160a01b0384163b155b156110db57604051639996b31560e01b81526001600160a01b0385166004820152602401610c3d565b50805b9392505050565b8051156110f55780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b80356001600160a01b0381168114611124575f5ffd5b919050565b5f5f6040838503121561113a575f5ffd5b6111438361110e565b91506111516020840161110e565b90509250929050565b5f6020828403121561116a575f5ffd5b5035919050565b5f5f60408385031215611182575f5ffd5b50508035926020909101359150565b5f5f83601f8401126111a1575f5ffd5b5081356001600160401b038111156111b7575f5ffd5b6020830191508360208285010111156111ce575f5ffd5b9250929050565b5f5f5f604084860312156111e7575f5ffd5b8335925060208401356001600160401b03811115611203575f5ffd5b61120f86828701611191565b9497909650939450505050565b5f5f5f6060848603121561122e575f5ffd5b6112378461110e565b95602085013595506040909401359392505050565b634e487b7160e01b5f52604160045260245ffd5b5f5f60408385031215611271575f5ffd5b61127a8361110e565b915060208301356001600160401b03811115611294575f5ffd5b8301601f810185136112a4575f5ffd5b80356001600160401b038111156112bd576112bd61124c565b604051601f8201601f19908116603f011681016001600160401b03811182821017156112eb576112eb61124c565b604052818152828201602001871015611302575f5ffd5b816020840160208301375f602083830101528093505050509250929050565b5f5f5f5f5f60808688031215611335575f5ffd5b61133e8661110e565b94506020860135935060408601356001600160401b0381111561135f575f5ffd5b61136b88828901611191565b96999598509660600135949350505050565b5f5f6040838503121561138e575f5ffd5b6113978361110e565b946020939093013593505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f5f602083850312156113eb575f5ffd5b82356001600160401b03811115611400575f5ffd5b61140c85828601611191565b90969095509350505050565b5f5f5f6060848603121561142a575f5ffd5b6114338461110e565b92506114416020850161110e565b915061144f6040850161110e565b90509250925092565b5f5f83601f840112611468575f5ffd5b5081356001600160401b0381111561147e575f5ffd5b6020830191508360208260051b85010111156111ce575f5ffd5b5f5f602083850312156114a9575f5ffd5b82356001600160401b038111156114be575f5ffd5b61140c85828601611458565b5f5f5f5f5f5f5f5f6080898b0312156114e1575f5ffd5b88356001600160401b038111156114f6575f5ffd5b6115028b828c01611458565b90995097505060208901356001600160401b03811115611520575f5ffd5b61152c8b828c01611458565b90975095505060408901356001600160401b0381111561154a575f5ffd5b6115568b828c01611458565b90955093505060608901356001600160401b03811115611574575f5ffd5b6115808b828c01611458565b999c989b5096995094979396929594505050565b5f602082840312156115a4575f5ffd5b6110de8261110e565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b602081525f6115e86020830184866115ad565b949350505050565b60018060a01b0386168152846020820152608060408201525f6116176080830185876115ad565b90508260608301529695505050505050565b8183525f6001600160fb1b03831115611640575f5ffd5b8260051b80836020870137939093016020019392505050565b602081525f6115e8602083018486611629565b608081525f61167f608083018a8c611629565b828103602084015261169281898b611629565b905082810360408401526116a7818789611629565b905082810360608401526116bc818587611629565b9b9a5050505050505050505050565b5f602082840312156116db575f5ffd5b5051919050565b5f82518060208501845e5f92019182525091905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca2646970667358221220bdc88220ee10109405383043d276b2402778177b22ef92e76a2321370bbd62fd64736f6c634300081b0033', + ]); + await ethers.provider.send('hardhat_setCode', [ + nodeDriverAuthProxy, + '0x6080604052600a600c565b005b60186014601a565b6051565b565b6000604c7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b3660008037600080366000845af43d6000803e808015606f573d6000f35b3d6000fdfea2646970667358221220d0232cfa81216c3e4973e570f043b57ccb69ae4a81b8bc064338713721c87a9f64736f6c63430008140033', + ]); + await ethers.provider.send('hardhat_setCode', [ + nodeDriverAuth, + '0x60806040526004361061013c575f3560e01c806379bead38116100b3578063c0c53b8b1161006d578063c0c53b8b1461036d578063d6a0c7af1461038c578063e08d7e66146103ab578063ebdf104c146103ca578063f2fde38b146103e9578063fd1b6ec114610408575f5ffd5b806379bead38146102885780638da5cb5b146102a7578063a4066fbe146102d3578063a8ab09ba146102f2578063ad3cb1cc14610311578063b9cc6b1c1461034e575f5ffd5b80634b64e492116101045780634b64e492146101dd5780634f1ef286146101fc57806352d1902d1461020f57806366e7ea0f14610236578063715018a61461025557806376fed43a14610269575f5ffd5b80630aeeca00146101405780631cef4fab146101615780631e702f8314610180578063242a6e3f1461019f578063267ab446146101be575b5f5ffd5b34801561014b575f5ffd5b5061015f61015a366004611136565b610427565b005b34801561016c575f5ffd5b5061015f61017b366004611161565b61048b565b34801561018b575f5ffd5b5061015f61019a3660046111a4565b6104a5565b3480156101aa575f5ffd5b5061015f6101b9366004611208565b610534565b3480156101c9575f5ffd5b5061015f6101d8366004611136565b6105c4565b3480156101e8575f5ffd5b5061015f6101f736600461124f565b6105fd565b61015f61020a36600461127e565b610628565b34801561021a575f5ffd5b50610223610647565b6040519081526020015b60405180910390f35b348015610241575f5ffd5b5061015f610250366004611341565b610662565b348015610260575f5ffd5b5061015f6106e2565b348015610274575f5ffd5b5061015f61028336600461136b565b6106f5565b348015610293575f5ffd5b5061015f6102a2366004611341565b61078b565b3480156102b2575f5ffd5b506102bb6107cc565b6040516001600160a01b03909116815260200161022d565b3480156102de575f5ffd5b5061015f6102ed3660046111a4565b6107fa565b3480156102fd575f5ffd5b5061015f61030c3660046113c9565b61085c565b34801561031c575f5ffd5b50610341604051806040016040528060058152602001640352e302e360dc1b81525081565b60405161022d91906113fb565b348015610359575f5ffd5b5061015f610368366004611430565b6108c6565b348015610378575f5ffd5b5061015f61038736600461146e565b610900565b348015610397575f5ffd5b5061015f6103a63660046114b6565b610a45565b3480156103b6575f5ffd5b5061015f6103c536600461152d565b610a87565b3480156103d5575f5ffd5b5061015f6103e436600461155f565b610ae3565b3480156103f4575f5ffd5b5061015f61040336600461124f565b610b82565b348015610413575f5ffd5b5061015f6104223660046114b6565b610bc1565b61042f610bf4565b6001546040516205776560e91b8152600481018390526001600160a01b0390911690630aeeca00906024015b5f604051808303815f87803b158015610472575f5ffd5b505af1158015610484573d5f5f3e3d5ffd5b5050505050565b610493610bf4565b61049f84848484610c26565b50505050565b6001546001600160a01b031633146104d057604051630607323760e11b815260040160405180910390fd5b5f54604051631e702f8360e01b815260048101849052602481018390526001600160a01b0390911690631e702f83906044015b5f604051808303815f87803b15801561051a575f5ffd5b505af115801561052c573d5f5f3e3d5ffd5b505050505050565b5f546001600160a01b0316331461055e5760405163d42fccad60e01b815260040160405180910390fd5b60015460405163242a6e3f60e01b81526001600160a01b039091169063242a6e3f9061059290869086908690600401611651565b5f604051808303815f87803b1580156105a9575f5ffd5b505af11580156105bb573d5f5f3e3d5ffd5b50505050505050565b6105cc610bf4565b60015460405163133d5a2360e11b8152600481018390526001600160a01b039091169063267ab4469060240161045b565b610605610bf4565b610625816106116107cc565b303f6001546001600160a01b03163f610c26565b50565b610630610cd3565b61063982610d77565b6106438282610d7f565b5050565b5f610650610e40565b505f5160206117b65f395f51905f5290565b5f546001600160a01b0316331461068c5760405163d42fccad60e01b815260040160405180910390fd5b6001546001600160a01b039081169063e30443bc9084906106b1908590831631611673565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401610503565b6106ea610bf4565b6106f35f610e89565b565b6001546001600160a01b0316331461072057604051630607323760e11b815260040160405180910390fd5b5f54604051633b7f6a1d60e11b81526001600160a01b03909116906376fed43a906107579088908890889088908890600401611692565b5f604051808303815f87803b15801561076e575f5ffd5b505af1158015610780573d5f5f3e3d5ffd5b505050505050505050565b610793610bf4565b600154604051630f37d5a760e31b81526001600160a01b03848116600483015260248201849052909116906379bead3890604401610503565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b5f546001600160a01b031633146108245760405163d42fccad60e01b815260040160405180910390fd5b60015460405163520337df60e11b815260048101849052602481018390526001600160a01b039091169063a4066fbe90604401610503565b6001546001600160a01b0316331461088757604051630607323760e11b815260040160405180910390fd5b5f5460405163545584dd60e11b81526001600160a01b03858116600483015260248201859052604482018490529091169063a8ab09ba90606401610592565b6108ce610bf4565b600154604051632e731ac760e21b81526001600160a01b039091169063b9cc6b1c9061050390859085906004016116cb565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f811580156109445750825b90505f826001600160401b0316600114801561095f5750303b155b90508115801561096d575080155b1561098b5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156109b557845460ff60401b1916600160401b1785555b6109be86610ef9565b6109c6610f0a565b600180546001600160a01b03808a166001600160a01b0319928316179092555f8054928b16929091169190911790558315610a3b57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b610a4d610bf4565b60015460405163d6a0c7af60e01b81526001600160a01b03848116600483015283811660248301529091169063d6a0c7af90604401610503565b6001546001600160a01b03163314610ab257604051630607323760e11b815260040160405180910390fd5b5f54604051637046bf3360e11b81526001600160a01b039091169063e08d7e66906105039085908590600401611716565b6001546001600160a01b03163314610b0e57604051630607323760e11b815260040160405180910390fd5b5f54604051633af7c41360e21b81526001600160a01b039091169063ebdf104c90610b4b908b908b908b908b908b908b908b908b90600401611729565b5f604051808303815f87803b158015610b62575f5ffd5b505af1158015610b74573d5f5f3e3d5ffd5b505050505050505050505050565b610b8a610bf4565b6001600160a01b038116610bb857604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b61062581610e89565b610bc9610bf4565b813b1580610bd65750803b155b15610a4d57604051636f7c43f160e01b815260040160405180910390fd5b33610bfd6107cc565b6001600160a01b0316146106f35760405163118cdaa760e01b8152336004820152602401610baf565b610c2f84610e89565b836001600160a01b031663614619546040518163ffffffff1660e01b81526004015f604051808303815f87803b158015610c67575f5ffd5b505af1158015610c79573d5f5f3e3d5ffd5b50505050610c8683610e89565b81303f14610ca7576040516311387fef60e21b815260040160405180910390fd5b6001546001600160a01b03163f811461049f5760405163f0c300ef60e01b815260040160405180910390fd5b306001600160a01b037f000000000000000000000000d100ae0000000000000000000000000000000001161480610d5957507f000000000000000000000000d100ae00000000000000000000000000000000016001600160a01b0316610d4d5f5160206117b65f395f51905f52546001600160a01b031690565b6001600160a01b031614155b156106f35760405163703e46dd60e11b815260040160405180910390fd5b610625610bf4565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610dd9575060408051601f3d908101601f19168201909252610dd691810190611788565b60015b610e0157604051634c9c8ce360e01b81526001600160a01b0383166004820152602401610baf565b5f5160206117b65f395f51905f528114610e3157604051632a87526960e21b815260048101829052602401610baf565b610e3b8383610f12565b505050565b306001600160a01b037f000000000000000000000000d100ae000000000000000000000000000000000116146106f35760405163703e46dd60e11b815260040160405180910390fd5b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b610f01610f67565b61062581610fb0565b6106f3610f67565b610f1b82610fb8565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a2805115610f5f57610e3b828261101b565b61064361108f565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff166106f357604051631afcd79f60e31b815260040160405180910390fd5b610b8a610f67565b806001600160a01b03163b5f03610fed57604051634c9c8ce360e01b81526001600160a01b0382166004820152602401610baf565b5f5160206117b65f395f51905f5280546001600160a01b0319166001600160a01b0392909216919091179055565b60605f5f846001600160a01b031684604051611037919061179f565b5f60405180830381855af49150503d805f811461106f576040519150601f19603f3d011682016040523d82523d5f602084013e611074565b606091505b50915091506110848583836110ae565b925050505b92915050565b34156106f35760405163b398979f60e01b815260040160405180910390fd5b6060826110c3576110be8261110d565b611106565b81511580156110da57506001600160a01b0384163b155b1561110357604051639996b31560e01b81526001600160a01b0385166004820152602401610baf565b50805b9392505050565b80511561111d5780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b5f60208284031215611146575f5ffd5b5035919050565b6001600160a01b0381168114610625575f5ffd5b5f5f5f5f60808587031215611174575f5ffd5b843561117f8161114d565b9350602085013561118f8161114d565b93969395505050506040820135916060013590565b5f5f604083850312156111b5575f5ffd5b50508035926020909101359150565b5f5f83601f8401126111d4575f5ffd5b5081356001600160401b038111156111ea575f5ffd5b602083019150836020828501011115611201575f5ffd5b9250929050565b5f5f5f6040848603121561121a575f5ffd5b8335925060208401356001600160401b03811115611236575f5ffd5b611242868287016111c4565b9497909650939450505050565b5f6020828403121561125f575f5ffd5b81356111068161114d565b634e487b7160e01b5f52604160045260245ffd5b5f5f6040838503121561128f575f5ffd5b823561129a8161114d565b915060208301356001600160401b038111156112b4575f5ffd5b8301601f810185136112c4575f5ffd5b80356001600160401b038111156112dd576112dd61126a565b604051601f8201601f19908116603f011681016001600160401b038111828210171561130b5761130b61126a565b604052818152828201602001871015611322575f5ffd5b816020840160208301375f602083830101528093505050509250929050565b5f5f60408385031215611352575f5ffd5b823561135d8161114d565b946020939093013593505050565b5f5f5f5f5f6080868803121561137f575f5ffd5b853561138a8161114d565b94506020860135935060408601356001600160401b038111156113ab575f5ffd5b6113b7888289016111c4565b96999598509660600135949350505050565b5f5f5f606084860312156113db575f5ffd5b83356113e68161114d565b95602085013595506040909401359392505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f5f60208385031215611441575f5ffd5b82356001600160401b03811115611456575f5ffd5b611462858286016111c4565b90969095509350505050565b5f5f5f60608486031215611480575f5ffd5b833561148b8161114d565b9250602084013561149b8161114d565b915060408401356114ab8161114d565b809150509250925092565b5f5f604083850312156114c7575f5ffd5b82356114d28161114d565b915060208301356114e28161114d565b809150509250929050565b5f5f83601f8401126114fd575f5ffd5b5081356001600160401b03811115611513575f5ffd5b6020830191508360208260051b8501011115611201575f5ffd5b5f5f6020838503121561153e575f5ffd5b82356001600160401b03811115611553575f5ffd5b611462858286016114ed565b5f5f5f5f5f5f5f5f6080898b031215611576575f5ffd5b88356001600160401b0381111561158b575f5ffd5b6115978b828c016114ed565b90995097505060208901356001600160401b038111156115b5575f5ffd5b6115c18b828c016114ed565b90975095505060408901356001600160401b038111156115df575f5ffd5b6115eb8b828c016114ed565b90955093505060608901356001600160401b03811115611609575f5ffd5b6116158b828c016114ed565b999c989b5096995094979396929594505050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b838152604060208201525f61166a604083018486611629565b95945050505050565b8082018082111561108957634e487b7160e01b5f52601160045260245ffd5b60018060a01b0386168152846020820152608060408201525f6116b9608083018587611629565b90508260608301529695505050505050565b602081525f6116de602083018486611629565b949350505050565b8183525f6001600160fb1b038311156116fd575f5ffd5b8260051b80836020870137939093016020019392505050565b602081525f6116de6020830184866116e6565b608081525f61173c608083018a8c6116e6565b828103602084015261174f81898b6116e6565b905082810360408401526117648187896116e6565b905082810360608401526117798185876116e6565b9b9a5050505050505050505050565b5f60208284031215611798575f5ffd5b5051919050565b5f82518060208501845e5f92019182525091905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca26469706673582212200fba8519240038d84f6804c340b790638cbf2c931500716f7db1555007e0c33264736f6c634300081b0033', + ]); + await ethers.provider.send('hardhat_setCode', [ + sfcProxy, + '0x6080604052600a600c565b005b60186014601a565b6051565b565b6000604c7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b3660008037600080366000845af43d6000803e808015606f573d6000f35b3d6000fdfea2646970667358221220d0232cfa81216c3e4973e570f043b57ccb69ae4a81b8bc064338713721c87a9f64736f6c63430008140033', + ]); + await ethers.provider.send('hardhat_setCode', [ + sfc, + '0x6080604052600436106103d7575f3560e01c80638cddb015116101ff578063c65ee0e111610113578063dc31e1af116100a8578063e880a15911610078578063e880a15914610e10578063e9a505a714610e2f578063ebdf104c14610e4e578063f2fde38b14610e6d578063fb36025f14610e8c575f5ffd5b8063dc31e1af14610d43578063df00c92214610d7d578063e08d7e6614610db7578063e261641a14610dd6575f5ffd5b8063cfd47663116100e3578063cfd4766314610ca3578063d46fa51814610cd9578063d725e91f14610cf6578063db5ca3e514610d15575f5ffd5b8063c65ee0e114610c25578063c7be95de14610c50578063cc17278414610c65578063cc8343aa14610c84575f5ffd5b8063a86a056f11610194578063b0ef386c11610164578063b0ef386c14610ad8578063b5d8962714610af7578063b88a37e214610b9a578063c3de580e14610bc6578063c5f956af14610c06575f5ffd5b8063a86a056f146109f8578063a8ab09ba14610a2e578063aa5d829214610a4d578063ad3cb1cc14610aa8575f5ffd5b80639fa6dd35116101cf5780639fa6dd3514610979578063a198d2291461098c578063a5820daa146109c6578063a5a470ad146109e5575f5ffd5b80638cddb015146108ea5780638d2da32e146109095780638da5cb5b1461091e57806390a6c4751461095a575f5ffd5b806352d1902d116102f6578063736de9ae1161028b578063841e45611161025b578063841e45611461085757806384b863e014610876578063854873e11461088a578063860c2750146108b65780638b0e9f3f146108d5575f5ffd5b8063736de9ae146107db578063766718081461080f57806376fed43a146108235780637cacb1d614610842575f5ffd5b80636099ecb2116102c65780636099ecb21461072d57806361e53fcc1461074c5780636f49866314610786578063715018a6146107c7575f5ffd5b806352d1902d146106bd57806354fd4d50146106d15780635601fe01146106ef57806358f95b801461070e575f5ffd5b806339b80c001161036c57806346f1ca351161033c57806346f1ca351461064d5780634f1ef2861461066c5780634f7c4efb1461067f5780634f864df41461069e575f5ffd5b806339b80c001461055d5780633fbfd4df146105db578063441a3e70146105fa578063468f35ee14610619575f5ffd5b806318160ddd116103a757806318160ddd146104ae5780631e702f83146104c35780631f270152146104e257806328f7314814610548575f5ffd5b80630135b1db146103f957806308c3687414610437578063093b41d0146104585780630962ef791461048f575f5ffd5b366103f55760405163ab064ad360e01b815260040160405180910390fd5b5f5ffd5b348015610404575f5ffd5b506104246104133660046145a6565b60036020525f908152604090205481565b6040519081526020015b60405180910390f35b348015610442575f5ffd5b506104566104513660046145c1565b610eb7565b005b348015610463575f5ffd5b50601254610477906001600160a01b031681565b6040516001600160a01b03909116815260200161042e565b34801561049a575f5ffd5b506104566104a93660046145c1565b610f19565b3480156104b9575f5ffd5b50610424600d5481565b3480156104ce575f5ffd5b506104566104dd3660046145d8565b610fe9565b3480156104ed575f5ffd5b5061052d6104fc3660046145f8565b600b60209081525f938452604080852082529284528284209052825290208054600182015460029092015490919083565b6040805193845260208401929092529082015260600161042e565b348015610553575f5ffd5b5061042460075481565b348015610568575f5ffd5b506105ae6105773660046145c1565b600e6020525f9081526040902060088101546009820154600a830154600b840154600c850154600d90950154939492939192909186565b604080519687526020870195909552938501929092526060840152608083015260a082015260c00161042e565b3480156105e6575f5ffd5b506104566105f536600461462a565b611072565b348015610605575f5ffd5b506104566106143660046145d8565b6111db565b348015610624575f5ffd5b506104776106333660046145a6565b60156020525f90815260409020546001600160a01b031681565b348015610658575f5ffd5b506104566106673660046145a6565b6111f3565b61045661067a366004614699565b61122b565b34801561068a575f5ffd5b506104566106993660046145d8565b611246565b3480156106a9575f5ffd5b506104566106b836600461475c565b6112f5565b3480156106c8575f5ffd5b50610424611442565b3480156106dc575f5ffd5b50604051600160fa1b815260200161042e565b3480156106fa575f5ffd5b506104246107093660046145c1565b61145d565b348015610719575f5ffd5b506104246107283660046145d8565b61148f565b348015610738575f5ffd5b50610424610747366004614785565b6114af565b348015610757575f5ffd5b506104246107663660046145d8565b5f918252600e602090815260408084209284526001909201905290205490565b348015610791575f5ffd5b506104246107a0366004614785565b6001600160a01b03919091165f908152600960209081526040808320938352929052205490565b3480156107d2575f5ffd5b506104566114f4565b3480156107e6575f5ffd5b506104776107f53660046145a6565b60166020525f90815260409020546001600160a01b031681565b34801561081a575f5ffd5b50610424611507565b34801561082e575f5ffd5b5061045661083d3660046147f3565b61151c565b34801561084d575f5ffd5b5061042460015481565b348015610862575f5ffd5b506104566108713660046145a6565b61156e565b348015610881575f5ffd5b50610456611598565b348015610895575f5ffd5b506108a96108a43660046145c1565b61169d565b60405161042e919061487f565b3480156108c1575f5ffd5b506104566108d03660046145a6565b611734565b3480156108e0575f5ffd5b5061042460065481565b3480156108f5575f5ffd5b50610456610904366004614785565b61175e565b348015610914575f5ffd5b5061042460085481565b348015610929575f5ffd5b507f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b0316610477565b348015610965575f5ffd5b506104566109743660046145c1565b611785565b6104566109873660046145c1565b611799565b348015610997575f5ffd5b506104246109a63660046145d8565b5f918252600e602090815260408084209284526006909201905290205490565b3480156109d1575f5ffd5b506104566109e03660046145c1565b6117a4565b6104566109f3366004614891565b611927565b348015610a03575f5ffd5b50610424610a12366004614785565b600a60209081525f928352604080842090915290825290205481565b348015610a39575f5ffd5b50610456610a483660046145f8565b611a6e565b348015610a58575f5ffd5b50610a90610a673660046145d8565b5f918252600e60209081526040808420928452600390920190529020546001600160401b031690565b6040516001600160401b03909116815260200161042e565b348015610ab3575f5ffd5b506108a9604051806040016040528060058152602001640352e302e360dc1b81525081565b348015610ae3575f5ffd5b50610456610af23660046145a6565b611aad565b348015610b02575f5ffd5b50610b57610b113660046145c1565b600260208190525f918252604090912080546001820154928201546003830154600484015460058501546006909501549395946001600160a01b03909316939192909187565b6040805197885260208801969096526001600160a01b03909416948601949094526060850191909152608084015260a083019190915260c082015260e00161042e565b348015610ba5575f5ffd5b50610bb9610bb43660046145c1565b611b05565b60405161042e91906148cf565b348015610bd1575f5ffd5b50610bf6610be03660046145c1565b5f90815260026020526040902054608016151590565b604051901515815260200161042e565b348015610c11575f5ffd5b50601054610477906001600160a01b031681565b348015610c30575f5ffd5b50610424610c3f3660046145c1565b600f6020525f908152604090205481565b348015610c5b575f5ffd5b5061042460055481565b348015610c70575f5ffd5b50610456610c7f366004614911565b611b67565b348015610c8f575f5ffd5b50610456610c9e366004614948565b611c2d565b348015610cae575f5ffd5b50610424610cbd366004614785565b600c60209081525f928352604080842090915290825290205481565b348015610ce4575f5ffd5b506011546001600160a01b0316610477565b348015610d01575f5ffd5b50610456610d103660046145a6565b611d57565b348015610d20575f5ffd5b50610424610d2f3660046145c1565b5f908152600e602052604090206009015490565b348015610d4e575f5ffd5b50610424610d5d3660046145d8565b5f918252600e602090815260408084209284526004909201905290205490565b348015610d88575f5ffd5b50610424610d973660046145d8565b5f918252600e602090815260408084209284526002909201905290205490565b348015610dc2575f5ffd5b50610456610dd13660046149af565b611dfd565b348015610de1575f5ffd5b50610424610df03660046145d8565b5f918252600e602090815260408084209284526005909201905290205490565b348015610e1b575f5ffd5b50610456610e2a3660046145a6565b611ebe565b348015610e3a575f5ffd5b50601454610477906001600160a01b031681565b348015610e59575f5ffd5b50610456610e683660046149e1565b611ee8565b348015610e78575f5ffd5b50610456610e873660046145a6565b61218c565b348015610e97575f5ffd5b50610424610ea63660046145a6565b60136020525f908152604090205481565b335f610ec382846121cb565b9050610ed082848361224e565b82826001600160a01b03167f663e0f63f4fc6b01be195c4b56111fd6f14b947d6264497119b08daf77e26da583604051610f0c91815260200190565b60405180910390a3505050565b335f610f2582846121cb565b90505f610f31836122db565b6001600160a01b0316826040515f6040518083038185875af1925050503d805f8114610f78576040519150601f19603f3d011682016040523d82523d5f602084013e610f7d565b606091505b5050905080610f9f576040516312171d8360e31b815260040160405180910390fd5b83836001600160a01b03167f70de20a533702af05c8faf1637846c4586a021bbc71b6928b089b6d555e4fbc284604051610fdb91815260200190565b60405180910390a350505050565b5f546001600160a01b031633146110135760405163c78d372960e01b815260040160405180910390fd5b806110315760405163396bd83560e21b815260040160405180910390fd5b61103b8282612303565b611045825f611c2d565b5f828152600260208190526040822001546001600160a01b03169061106d9082908190612405565b505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f811580156110b65750825b90505f826001600160401b031660011480156110d15750303b155b9050811580156110df575080155b156110fd5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561112757845460ff60401b1916600160401b1785555b611130866124e1565b6111386124f2565b60018a90555f80546001600160a01b03808b166001600160a01b03199283161790925560118054928a1692909116919091179055600d8990556111784290565b5f8b8152600e602052604090206008015583156111cf57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050565b6111ef3383836111ea336122db565b6124fa565b5050565b6040516001600160a01b0382169033907f857125196131cfcd709c738c6d1fd2701ce70f2a03785aeadae6f4b47fe73c1d905f90a350565b611233612894565b61123c82612938565b6111ef8282612940565b61124e6129fc565b5f8281526002602052604090205460801661127c576040516321b6a8f960e11b815260040160405180910390fd5b670de0b6b3a76400008111156112a5576040516357c70d6360e01b815260040160405180910390fd5b5f828152600f6020526040908190208290555182907f047575f43f09a7a093d94ec483064acfc61b7e25c0de28017da442abf99cb917906112e99084815260200190565b60405180910390a25050565b336113008185612a57565b50815f0361132157604051631f2a200560e01b815260040160405180910390fd5b6001600160a01b0381165f908152600b6020908152604080832087845282528083208684529091529020600201541561136d5760405163756f5c2d60e11b815260040160405180910390fd5b61137d81858460015f6001612ac5565b6001600160a01b0381165f908152600b60209081526040808320878452825280832086845290915290206002018290556113b5611507565b6001600160a01b0382165f908152600b6020908152604080832088845282528083208784529091528120918255426001909201919091556113f7908590611c2d565b8284826001600160a01b03167fd3bb4e423fbea695d16b982f9f682dc5f35152e5411646a8a5a79a6b02ba8d578560405161143491815260200190565b60405180910390a450505050565b5f61144b612c96565b505f516020614eb75f395f51905f5290565b5f818152600260208181526040808420909201546001600160a01b03168352600c815281832093835292909252205490565b5f828152600e602090815260408083208484529091529020545b92915050565b5f5f6114bb8484612cdf565b6001600160a01b0385165f9081526009602090815260408083208784529091529020549091506114ec908290614abf565b949350505050565b6114fc6129fc565b6115055f612d49565b565b5f60015460016115179190614abf565b905090565b5f546001600160a01b031633146115465760405163c78d372960e01b815260040160405180910390fd5b611557858585855f5f875f5f612db9565b6005548411156115675760058490555b5050505050565b6115766129fc565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b6010546001600160a01b03166115c15760405163b2c4cce960e01b815260040160405180910390fd5b6008545f036115e35760405163211a852360e21b815260040160405180910390fd5b600880545f918290556010546040519192916001600160a01b0390911690620f424090849084818181858888f193505050503d805f811461163f576040519150601f19603f3d011682016040523d82523d5f602084013e611644565b606091505b5050905080611666576040516312171d8360e31b815260040160405180910390fd5b6040518281527f6dd5bb8ebf4cfb647c1cc0e9364ed9ecbf56202f7d3c9f058473df82664478d89060200160405180910390a15050565b60046020525f9081526040902080546116b590614ad2565b80601f01602080910402602001604051908101604052809291908181526020018280546116e190614ad2565b801561172c5780601f106117035761010080835404028352916020019161172c565b820191905f5260205f20905b81548152906001019060200180831161170f57829003601f168201915b505050505081565b61173c6129fc565b601180546001600160a01b0319166001600160a01b0392909216919091179055565b6117688282612a57565b6111ef5760405163208e0a4160e11b815260040160405180910390fd5b61178d6129fc565b61179681612f64565b50565b61179633823461224e565b6117ac6129fc565b601154604080516375840fab60e01b815290515f926001600160a01b0316916375840fab9160048083019260209291908290030181865afa1580156117f3573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118179190614b0a565b6001600160a01b03160361183e5760405163d92e233d60e01b815260040160405180910390fd5b5f54601154604080516375840fab60e01b815290516001600160a01b03938416936366e7ea0f9316916375840fab9160048083019260209291908290030181865afa15801561188f573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118b39190614b0a565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602481018490526044015f604051808303815f87803b1580156118f8575f5ffd5b505af115801561190a573d5f5f3e3d5ffd5b5050505080600d5f82825461191f9190614abf565b909155505050565b60115f9054906101000a90046001600160a01b03166001600160a01b031663c5f530af6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611977573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061199b9190614b25565b3410156119bb5760405163047447a360e11b815260040160405180910390fd5b6042811415806119f4575081815f8181106119d8576119d8614b3c565b9050013560f81c60f81b6001600160f81b03191660c060f81b14155b15611a12576040516338497f4960e11b815260040160405180910390fd5b60135f611a1f8484612fcb565b6001600160a01b0316815260208101919091526040015f205415611a565760405163028aeb6760e21b815260040160405180910390fd5b611a61338383612ff7565b6111ef336005543461224e565b5f546001600160a01b03163314611a985760405163c78d372960e01b815260040160405180910390fd5b611aa48383835f613025565b61106d81613173565b611ab56129fc565b6014546001600160a01b03808316911603611ae357604051639b92bed360e01b815260040160405180910390fd5b601480546001600160a01b0319166001600160a01b0392909216919091179055565b5f818152600e6020908152604091829020600701805483518184028101840190945280845260609392830182828015611b5b57602002820191905f5260205f20905b815481526020019060010190808311611b47575b50505050509050919050565b6014546001600160a01b03163314611b925760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b038281165f90815260166020526040902054818316911603611bce5760405163eb81e1a360e01b815260040160405180910390fd5b806001600160a01b0316826001600160a01b031603611c005760405163367558c360e01b815260040160405180910390fd5b6001600160a01b039182165f90815260156020526040902080546001600160a01b03191691909216179055565b5f82815260026020526040902060040154611c5b57604051635926e0c360e01b815260040160405180910390fd5b5f8281526002602052604090206001810154905415611c7757505f5b5f5460405163520337df60e11b815260048101859052602481018390526001600160a01b039091169063a4066fbe906044015f604051808303815f87803b158015611cc0575f5ffd5b505af1158015611cd2573d5f5f3e3d5ffd5b50505050818015611ce257508015155b1561106d575f805484825260046020819052604092839020925163242a6e3f60e01b81526001600160a01b039092169263242a6e3f92611d259288929101614b50565b5f604051808303815f87803b158015611d3c575f5ffd5b505af1158015611d4e573d5f5f3e3d5ffd5b50505050505050565b336001600160a01b038216611d7f5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b038181165f90815260156020526040902054811690831614611dbb57604051630fe3b3c160e31b815260040160405180910390fd5b6001600160a01b039081165f9081526016602090815260408083208054949095166001600160a01b031994851617909455601590529190912080549091169055565b5f546001600160a01b03163314611e275760405163c78d372960e01b815260040160405180910390fd5b5f600e5f611e33611507565b81526020019081526020015f2090505f5f90505b82811015611ea9575f848483818110611e6257611e62614b3c565b602090810292909201355f81815260028452604080822060010154948890529020839055600c860154909350611e9a91508290614abf565b600c8501555050600101611e47565b50611eb8600782018484614535565b50505050565b611ec66129fc565b601280546001600160a01b0319166001600160a01b0392909216919091179055565b5f546001600160a01b03163314611f125760405163c78d372960e01b815260040160405180910390fd5b5f600e5f611f1e611507565b81526020019081526020015f2090505f81600701805480602002602001604051908101604052809291908181526020018280548015611f7a57602002820191905f5260205f20905b815481526020019060010190808311611f66575b50505050509050611fff82828c8c808060200260200160405190810160405280939291908181526020018383602002808284375f81840152601f19601f820116905080830192505050505050508b8b808060200260200160405190810160405280939291908181526020018383602002808284375f920191909152506131e592505050565b600180545f908152600e60205260409020600881015490919042111561203157600882015461202e9042614bde565b90505b6120b1818584868c8c808060200260200160405190810160405280939291908181526020018383602002808284375f81840152601f19601f820116905080830192505050505050508b8b808060200260200160405190810160405280939291908181526020018383602002808284375f920191909152506133ff92505050565b6120f0818584868c8c808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250613b3992505050565b50506120fa611507565b6001554260088301554360098301556011546040805163d9a7c1f960e01b815290516001600160a01b039092169163d9a7c1f9916004808201926020929091908290030181865afa158015612151573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121759190614b25565b600b83015550600d80549101555050505050505050565b6121946129fc565b6001600160a01b0381166121c257604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b61179681612d49565b5f6121d68383612a57565b506001600160a01b0383165f9081526009602090815260408083208584529091528120549081900361221b5760405163899aaa9d60e01b815260040160405180910390fd5b6001600160a01b0384165f90815260096020908152604080832086845290915281205561224781613173565b9392505050565b5f8281526002602052604090206004015461227c57604051635926e0c360e01b815260040160405180910390fd5b5f82815260026020526040902054156122a8576040516353670afb60e11b815260040160405180910390fd5b6122b58383836001613025565b6122be82613db7565b61106d5760405163c2eb4ead60e01b815260040160405180910390fd5b6001600160a01b038082165f90815260166020526040812054909116806114a9575090919050565b5f8281526002602052604090205415801561231d57508015155b15612344575f828152600260205260409020600101546007546123409190614bde565b6007555b5f828152600260205260409020548111156111ef575f8281526002602052604081208281556006015490036123d35761237b611507565b5f8381526002602090815260409182902060068101849055426005909101819055825193845290830152805184927fac4801c32a6067ff757446524ee4e7a373797278ac3c883eac5c693b4ad72e4792908290030190a25b817fcd35267e7654194727477d6c78b541a553483cff7f92a055d17868d3da6e953e826040516112e991815260200190565b6012546001600160a01b03161561106d576012546040516001600160a01b03858116602483015284811660448301525f921690627a12009060640160408051601f198184030181529181526020820180516001600160e01b0316631fbcb08360e11b179052516124759190614bf1565b5f604051808303815f8787f1925050503d805f81146124af576040519150601f19603f3d011682016040523d82523d5f602084013e6124b4565b606091505b50509050801580156124c35750815b15611eb8576040516347b4be6960e11b815260040160405180910390fd5b6124e9613e6e565b61179681613eb7565b611505613e6e565b6001600160a01b0384165f908152600b60209081526040808320868452825280832085845282528083208151606081018352815480825260018301549482019490945260029091015491810191909152910361256957604051630fe3b3c160e31b815260040160405180910390fd5b60208082015182515f8781526002909352604090922060050154909190158015906125a357505f8681526002602052604090206005015482115b156125c35750505f84815260026020526040902060058101546006909101545b60115f9054906101000a90046001600160a01b03166001600160a01b031663b82b84276040518163ffffffff1660e01b8152600401602060405180830381865afa158015612613573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126379190614b25565b6126419083614abf565b42101561266157604051635ada9a9960e01b815260040160405180910390fd5b60115f9054906101000a90046001600160a01b03166001600160a01b031663650acd666040518163ffffffff1660e01b8152600401602060405180830381865afa1580156126b1573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126d59190614b25565b6126df9082614abf565b6126e7611507565b1015612706576040516323ea994d60e01b815260040160405180910390fd5b6001600160a01b0387165f908152600b60209081526040808320898452825280832088845282528083206002908101548a855290835281842054600f9093529083205490926080909216151591906127619084908490613ebf565b6001600160a01b038b165f908152600b602090815260408083208d845282528083208c84529091528120818155600181018290556002015590508083116127bb576040516318f967fb60e01b815260040160405180910390fd5b5f6001600160a01b0388166127d08386614bde565b6040515f81818185875af1925050503d805f8114612809576040519150601f19603f3d011682016040523d82523d5f602084013e61280e565b606091505b5050905080612830576040516312171d8360e31b815260040160405180910390fd5b61283982612f64565b888a6001600160a01b038d167f94ffd6b85c71b847775c89ef6496b93cee961bdc6ff827fd117f174f06f745ae6128708689614bde565b60408051918252602082018890520160405180910390a45050505050505050505050565b306001600160a01b037f000000000000000000000000fc00face0000000000000000000000000000000116148061291a57507f000000000000000000000000fc00face000000000000000000000000000000016001600160a01b031661290e5f516020614eb75f395f51905f52546001600160a01b031690565b6001600160a01b031614155b156115055760405163703e46dd60e11b815260040160405180910390fd5b6117966129fc565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561299a575060408051601f3d908101601f1916820190925261299791810190614b25565b60015b6129c257604051634c9c8ce360e01b81526001600160a01b03831660048201526024016121b9565b5f516020614eb75f395f51905f5281146129f257604051632a87526960e21b8152600481018290526024016121b9565b61106d8383613f25565b33612a2e7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b0316146115055760405163118cdaa760e01b81523360048201526024016121b9565b5f5f612a638484612cdf565b9050612a6e83613f7a565b6001600160a01b0385165f818152600a60209081526040808320888452825280832094909455918152600982528281208682529091529081208054839290612ab7908490614abf565b909155505015159392505050565b6001600160a01b0386165f908152600c6020908152604080832088845290915281208054869290612af7908490614bde565b90915550505f85815260026020526040902060010154612b18908590614bde565b5f86815260026020526040902060010155600654612b37908590614bde565b6006555f85815260026020526040902054612b5e5783600754612b5a9190614bde565b6007555b5f612b688661145d565b90508015801590612b8457505f86815260026020526040902054155b15612c645760115f9054906101000a90046001600160a01b03166001600160a01b031663c5f530af6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612bd9573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612bfd9190614b25565b811015612c2e578215612c235760405163047447a360e11b815260040160405180910390fd5b612c2e866001612303565b818015612c415750612c3f86613db7565b155b15612c5f5760405163c2eb4ead60e01b815260040160405180910390fd5b612c6f565b612c6f866001612303565b5f8681526002602081905260409091200154611d4e9088906001600160a01b031686612405565b306001600160a01b037f000000000000000000000000fc00face0000000000000000000000000000000116146115055760405163703e46dd60e11b815260040160405180910390fd5b6001600160a01b0382165f908152600a6020908152604080832084845290915281205481612d0c84613f7a565b6001600160a01b0386165f908152600c60209081526040808320888452909152812054919250612d3e82878686613fcf565b979650505050505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b6001600160a01b0389165f9081526003602052604090205415612def57604051633f4dc7d360e11b815260040160405180910390fd5b6001600160a01b0389165f8181526003602081815260408084208d90558c845260028083528185208b81559384018a905560048085018a90556005850188905560068501899055930180546001600160a01b0319169095179094555220612e57878983614c4b565b508760135f612e668a8a612fcb565b6001600160a01b03166001600160a01b031681526020019081526020015f2081905550886001600160a01b0316887f49bca1ed2666922f9f1690c26a569e1299c2a715fe57647d77e81adfabbf25bf8686604051612ece929190918252602082015260400190565b60405180910390a38115612f1857604080518381526020810183905289917fac4801c32a6067ff757446524ee4e7a373797278ac3c883eac5c693b4ad72e47910160405180910390a25b8415612f5957877fcd35267e7654194727477d6c78b541a553483cff7f92a055d17868d3da6e953e86604051612f5091815260200190565b60405180910390a25b505050505050505050565b8015611796576040515f9082156108fc0290839083818181858288f19350505050158015612f94573d5f5f3e3d5ffd5b506040518181527f8918bd6046d08b314e457977f29562c5d76a7030d79b1edba66e8a5da0b77ae89060200160405180910390a150565b5f612fd98260028186614d04565b604051612fe7929190614d2b565b6040519081900390209392505050565b5f60055f815461300690614d3a565b91829055509050611eb8848285855f61301d611507565b425f5f612db9565b815f0361304557604051631f2a200560e01b815260040160405180910390fd5b61304f8484612a57565b506001600160a01b0384165f908152600c6020908152604080832086845290915290205461307e908390614abf565b6001600160a01b0385165f908152600c602090815260408083208784528252808320939093556002905220600101546130b78382614abf565b5f858152600260205260409020600101556006546130d6908490614abf565b6006555f848152600260205260409020546130fd57826007546130f99190614abf565b6007555b613108848215611c2d565b83856001600160a01b03167f9a8f44850296624dadfd9c246d17e47171d35727a181bd090aa14bbbe00238bb8560405161314491815260200190565b60405180910390a35f84815260026020819052604090912001546115679086906001600160a01b031684612405565b5f546040516366e7ea0f60e01b8152306004820152602481018390526001600160a01b03909116906366e7ea0f906044015f604051808303815f87803b1580156131bb575f5ffd5b505af11580156131cd573d5f5f3e3d5ffd5b5050505080600d546131df9190614abf565b600d5550565b5f5b83518110156115675760115f9054906101000a90046001600160a01b03166001600160a01b0316635a68f01a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613240573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906132649190614b25565b82828151811061327657613276614b3c565b6020026020010151118015613316575060115f9054906101000a90046001600160a01b03166001600160a01b031662cc7f836040518163ffffffff1660e01b8152600401602060405180830381865afa1580156132d5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906132f99190614b25565b83828151811061330b5761330b614b3c565b602002602001015110155b156133625761333f84828151811061333057613330614b3c565b60200260200101516008612303565b61336284828151811061335457613354614b3c565b60200260200101515f611c2d565b82818151811061337457613374614b3c565b6020026020010151856005015f86848151811061339357613393614b3c565b602002602001015181526020019081526020015f20819055508181815181106133be576133be614b3c565b6020026020010151856006015f8684815181106133dd576133dd614b3c565b60209081029190910181015182528101919091526040015f20556001016131e7565b5f6040518060a0016040528085516001600160401b0381111561342457613424614685565b60405190808252806020026020018201604052801561344d578160200160208202803683370190505b5081526020015f815260200185516001600160401b0381111561347257613472614685565b60405190808252806020026020018201604052801561349b578160200160208202803683370190505b5081526020015f81526020015f81525090505f5f90505b84518110156135db575f866004015f8784815181106134d3576134d3614b3c565b602002602001015181526020019081526020015f205490505f5f90508185848151811061350257613502614b3c565b60200260200101511115613538578185848151811061352357613523614b3c565b60200260200101516135359190614bde565b90505b8986848151811061354b5761354b614b3c565b60200260200101518261355e9190614d52565b6135689190614d7d565b8460400151848151811061357e5761357e614b3c565b602002602001018181525050836040015183815181106135a0576135a0614b3c565b602002602001015184606001516135b79190614abf565b606085015260808401516135cc908290614abf565b608085015250506001016134b2565b505f5b84518110156136c857878482815181106135fa576135fa614b3c565b60200260200101518986848151811061361557613615614b3c565b60200260200101518a5f015f8a878151811061363357613633614b3c565b602002602001015181526020019081526020015f20546136539190614d52565b61365d9190614d7d565b6136679190614d52565b6136719190614d7d565b825180518390811061368557613685614b3c565b602090810291909101015281518051829081106136a4576136a4614b3c565b602002602001015182602001516136bb9190614abf565b60208301526001016135de565b505f5b84518110156139cc575f6137738960115f9054906101000a90046001600160a01b03166001600160a01b031663d9a7c1f96040518163ffffffff1660e01b8152600401602060405180830381865afa158015613729573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061374d9190614b25565b855180518690811061376157613761614b3c565b60200260200101518660200151614038565b90506137a583608001518460400151848151811061379357613793614b3c565b60200260200101518560600151614073565b6137af9082614abf565b90505f8683815181106137c4576137c4614b3c565b6020908102919091018101515f8181526002808452604080832090910154601154825163a778651560e01b815292519496506001600160a01b0391821695939461385c948994929093169263a778651592600480820193918290030181865afa158015613833573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906138579190614b25565b6141c4565b6001600160a01b0383165f908152600c6020908152604080832087845290915290205490915080156138c0576001600160a01b0383165f908152600960209081526040808320878452909152812080548492906138ba908490614abf565b90915550505b5f6138cb8387614bde565b5f86815260026020526040812060010154919250811561390557816138f8670de0b6b3a764000085614d52565b6139029190614d7d565b90505b5f87815260018f016020526040902054613920908290614abf565b8f6001015f8981526020019081526020015f20819055508a898151811061394957613949614b3c565b60200260200101518f6004015f8981526020019081526020015f20819055508b898151811061397a5761397a614b3c565b60200260200101518e6002015f8981526020019081526020015f20546139a09190614abf565b8f6002015f8981526020019081526020015f2081905550505050505050505080806001019150506136cb565b506080810151600a8701819055600d541115613a025785600a0154600d5f8282546139f79190614bde565b90915550613a079050565b5f600d555b6010546001600160a01b031615611d4e575f670de0b6b3a764000060115f9054906101000a90046001600160a01b03166001600160a01b03166394c3e9146040518163ffffffff1660e01b8152600401602060405180830381865afa158015613a72573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613a969190614b25565b8360800151613aa59190614d52565b613aaf9190614d7d565b9050613aba81613173565b6010546040515f916001600160a01b031690620f424090849084818181858888f193505050503d805f8114613b0a576040519150601f19603f3d011682016040523d82523d5f602084013e613b0f565b606091505b5050905080612f59578160085f828254613b299190614abf565b9091555050505050505050505050565b5f5b8251811015613daf575f838281518110613b5757613b57614b3c565b602002602001015190505f87613b72670de0b6b3a764000090565b858581518110613b8457613b84614b3c565b6020026020010151613b969190614d52565b613ba09190614d7d565b9050670de0b6b3a7640000811115613bbd5750670de0b6b3a76400005b5f8281526003870160209081526040808320815160608101835290546001600160401b038116825263ffffffff600160401b8204811694830194909452600160601b90049092169082015290613c1383836141e2565b5f85815260038b0160209081526040918290208351815485840151868601516001600160401b039093166bffffffffffffffffffffffff1990921691909117600160401b63ffffffff928316021763ffffffff60601b1916600160601b91909216021790556011548251631c25433760e01b815292519394506001600160a01b031692631c2543379260048082019392918290030181865afa158015613cbb573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613cdf9190614d90565b6001600160401b0316815f01516001600160401b0316108015613d85575060115f9054906101000a90046001600160a01b03166001600160a01b0316633fa225486040518163ffffffff1660e01b8152600401602060405180830381865afa158015613d4d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613d719190614db6565b63ffffffff16816040015163ffffffff1610155b15613d9f57613d95846010612303565b613d9f845f611c2d565b505060019092019150613b3b9050565b505050505050565b5f670de0b6b3a764000060115f9054906101000a90046001600160a01b03166001600160a01b0316632265f2846040518163ffffffff1660e01b8152600401602060405180830381865afa158015613e11573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613e359190614b25565b613e3e8461145d565b613e489190614d52565b613e529190614d7d565b5f92835260026020526040909220600101549190911115919050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff1661150557604051631afcd79f60e31b815260040160405180910390fd5b612194613e6e565b5f821580613ed55750670de0b6b3a76400008210155b15613ee157505f612247565b670de0b6b3a7640000613ef48382614bde565b613efe9086614d52565b613f089190614d7d565b613f13906001614abf565b90508381111561224757509192915050565b613f2e826143c5565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a2805115613f725761106d8282614428565b6111ef614491565b5f8181526002602052604081206006015415613fc7575f828152600260205260409020600601546001541015613fb257505060015490565b505f9081526002602052604090206006015490565b505060015490565b5f818310613fde57505f6114ec565b5f838152600e6020818152604080842088855260019081018352818520548786529383528185208986520190915290912054670de0b6b3a7640000876140248484614bde565b61402e9190614d52565b612d3e9190614d7d565b5f825f0361404757505f6114ec565b5f6140528587614d52565b90508261405f8583614d52565b6140699190614d7d565b9695505050505050565b5f825f0361408257505f612247565b5f8261408e8587614d52565b6140989190614d7d565b9050670de0b6b3a764000060115f9054906101000a90046001600160a01b03166001600160a01b03166394c3e9146040518163ffffffff1660e01b8152600401602060405180830381865afa1580156140f3573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906141179190614b25565b60115f9054906101000a90046001600160a01b03166001600160a01b031663c74dd6216040518163ffffffff1660e01b8152600401602060405180830381865afa158015614167573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061418b9190614b25565b61419d90670de0b6b3a7640000614bde565b6141a79190614bde565b6141b19083614d52565b6141bb9190614d7d565b95945050505050565b5f670de0b6b3a76400006141d88385614d52565b6122479190614d7d565b604080516060810182525f8082526020820181905291810191909152604080516060810182525f8082526020820181905291810191909152826040015163ffffffff165f03614245576001600160401b03841681526001604082015290506114a9565b5f836040015160016142579190614dd9565b63ffffffff1690505f846020015163ffffffff16866001600160401b0316865f01516001600160401b031660018561428f9190614df5565b6142999190614e14565b6142a39190614e3d565b6142ad9190614e3d565b90506142b98282614e5c565b6001600160401b031683526142ce8282614e89565b63ffffffff166020840152670de0b6b3a764000083516001600160401b031611156142ff57670de0b6b3a764000083525b60115f9054906101000a90046001600160a01b03166001600160a01b0316633fa225486040518163ffffffff1660e01b8152600401602060405180830381865afa15801561434f573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906143739190614db6565b63ffffffff16856040015163ffffffff1610156143aa57604085015161439a906001614dd9565b63ffffffff1660408401526143bb565b60408086015163ffffffff16908401525b5090949350505050565b806001600160a01b03163b5f036143fa57604051634c9c8ce360e01b81526001600160a01b03821660048201526024016121b9565b5f516020614eb75f395f51905f5280546001600160a01b0319166001600160a01b0392909216919091179055565b60605f5f846001600160a01b0316846040516144449190614bf1565b5f60405180830381855af49150503d805f811461447c576040519150601f19603f3d011682016040523d82523d5f602084013e614481565b606091505b50915091506141bb8583836144b0565b34156115055760405163b398979f60e01b815260040160405180910390fd5b6060826144c5576144c08261450c565b612247565b81511580156144dc57506001600160a01b0384163b155b1561450557604051639996b31560e01b81526001600160a01b03851660048201526024016121b9565b5080612247565b80511561451c5780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b828054828255905f5260205f2090810192821561456e579160200282015b8281111561456e578235825591602001919060010190614553565b5061457a92915061457e565b5090565b5b8082111561457a575f815560010161457f565b6001600160a01b0381168114611796575f5ffd5b5f602082840312156145b6575f5ffd5b813561224781614592565b5f602082840312156145d1575f5ffd5b5035919050565b5f5f604083850312156145e9575f5ffd5b50508035926020909101359150565b5f5f5f6060848603121561460a575f5ffd5b833561461581614592565b95602085013595506040909401359392505050565b5f5f5f5f5f60a0868803121561463e575f5ffd5b8535945060208601359350604086013561465781614592565b9250606086013561466781614592565b9150608086013561467781614592565b809150509295509295909350565b634e487b7160e01b5f52604160045260245ffd5b5f5f604083850312156146aa575f5ffd5b82356146b581614592565b915060208301356001600160401b038111156146cf575f5ffd5b8301601f810185136146df575f5ffd5b80356001600160401b038111156146f8576146f8614685565b604051601f8201601f19908116603f011681016001600160401b038111828210171561472657614726614685565b60405281815282820160200187101561473d575f5ffd5b816020840160208301375f602083830101528093505050509250929050565b5f5f5f6060848603121561476e575f5ffd5b505081359360208301359350604090920135919050565b5f5f60408385031215614796575f5ffd5b82356147a181614592565b946020939093013593505050565b5f5f83601f8401126147bf575f5ffd5b5081356001600160401b038111156147d5575f5ffd5b6020830191508360208285010111156147ec575f5ffd5b9250929050565b5f5f5f5f5f60808688031215614807575f5ffd5b853561481281614592565b94506020860135935060408601356001600160401b03811115614833575f5ffd5b61483f888289016147af565b96999598509660600135949350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f6122476020830184614851565b5f5f602083850312156148a2575f5ffd5b82356001600160401b038111156148b7575f5ffd5b6148c3858286016147af565b90969095509350505050565b602080825282518282018190525f918401906040840190835b818110156149065783518352602093840193909201916001016148e8565b509095945050505050565b5f5f60408385031215614922575f5ffd5b823561492d81614592565b9150602083013561493d81614592565b809150509250929050565b5f5f60408385031215614959575f5ffd5b823591506020830135801515811461493d575f5ffd5b5f5f83601f84011261497f575f5ffd5b5081356001600160401b03811115614995575f5ffd5b6020830191508360208260051b85010111156147ec575f5ffd5b5f5f602083850312156149c0575f5ffd5b82356001600160401b038111156149d5575f5ffd5b6148c38582860161496f565b5f5f5f5f5f5f5f5f6080898b0312156149f8575f5ffd5b88356001600160401b03811115614a0d575f5ffd5b614a198b828c0161496f565b90995097505060208901356001600160401b03811115614a37575f5ffd5b614a438b828c0161496f565b90975095505060408901356001600160401b03811115614a61575f5ffd5b614a6d8b828c0161496f565b90955093505060608901356001600160401b03811115614a8b575f5ffd5b614a978b828c0161496f565b999c989b5096995094979396929594505050565b634e487b7160e01b5f52601160045260245ffd5b808201808211156114a9576114a9614aab565b600181811c90821680614ae657607f821691505b602082108103614b0457634e487b7160e01b5f52602260045260245ffd5b50919050565b5f60208284031215614b1a575f5ffd5b815161224781614592565b5f60208284031215614b35575f5ffd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b828152604060208201525f5f8354614b6781614ad2565b806040860152600182165f8114614b855760018114614ba157614bd2565b60ff1983166060870152606082151560051b8701019350614bd2565b865f5260205f205f5b83811015614bc957815488820160600152600190910190602001614baa565b87016060019450505b50919695505050505050565b818103818111156114a9576114a9614aab565b5f82518060208501845e5f920191825250919050565b601f82111561106d57805f5260205f20601f840160051c81016020851015614c2c5750805b601f840160051c820191505b81811015611567575f8155600101614c38565b6001600160401b03831115614c6257614c62614685565b614c7683614c708354614ad2565b83614c07565b5f601f841160018114614ca7575f8515614c905750838201355b5f19600387901b1c1916600186901b178355611567565b5f83815260208120601f198716915b82811015614cd65786850135825560209485019460019092019101614cb6565b5086821015614cf2575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b5f5f85851115614d12575f5ffd5b83861115614d1e575f5ffd5b5050820193919092039150565b818382375f9101908152919050565b5f60018201614d4b57614d4b614aab565b5060010190565b80820281158282048414176114a9576114a9614aab565b634e487b7160e01b5f52601260045260245ffd5b5f82614d8b57614d8b614d69565b500490565b5f60208284031215614da0575f5ffd5b81516001600160401b0381168114612247575f5ffd5b5f60208284031215614dc6575f5ffd5b815163ffffffff81168114612247575f5ffd5b63ffffffff81811683821601908111156114a9576114a9614aab565b6001600160801b0382811682821603908111156114a9576114a9614aab565b6001600160801b038181168382160290811690818114614e3657614e36614aab565b5092915050565b6001600160801b0381811683821601908111156114a9576114a9614aab565b5f6001600160801b03831680614e7457614e74614d69565b806001600160801b0384160491505092915050565b5f6001600160801b03831680614ea157614ea1614d69565b806001600160801b038416069150509291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca264697066735822122066d19146273283f0e3b105875ee752668c5f6172f37ee249748d1d959cb7042564736f6c634300081b0033', + ]); + + // set proxy implementation addresses + await ethers.provider.send('hardhat_setStorageAt', [ + nodeDriverProxy, + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', + ethers.AbiCoder.defaultAbiCoder().encode(['address'], [nodeDriver]), + ]); + await ethers.provider.send('hardhat_setStorageAt', [ + nodeDriverAuthProxy, + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', + ethers.AbiCoder.defaultAbiCoder().encode(['address'], [nodeDriverAuth]), + ]); + await ethers.provider.send('hardhat_setStorageAt', [ + sfcProxy, + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', + ethers.AbiCoder.defaultAbiCoder().encode(['address'], [sfc]), + ]); + + // set implementations initialization status as initialized + await ethers.provider.send('hardhat_setStorageAt', [ + nodeDriver, + '0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00', + '0x000000000000000000000000000000000000000000000000ffffffffffffffff', + ]); + await ethers.provider.send('hardhat_setStorageAt', [ + nodeDriverAuth, + '0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00', + '0x000000000000000000000000000000000000000000000000ffffffffffffffff', + ]); + await ethers.provider.send('hardhat_setStorageAt', [ + sfc, + '0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00', + '0x000000000000000000000000000000000000000000000000ffffffffffffffff', + ]); + + // initialize the network + await ( + await ethers.getContractAt('NetworkInitializer', initializer) + ).initializeAll(epoch, totalSupply, sfcProxy, nodeDriverAuthProxy, nodeDriverProxy, evmWriter, owner); + + return { + owner, + user, + sfc, + sfcProxy, + nodeDriver, + nodeDriverProxy, + nodeDriverAuth, + nodeDriverAuthProxy, + evmWriter, + epoch, + totalSupply, + }; + }; + + beforeEach(async function () { + Object.assign(this, await loadFixture(fixture)); + }); + + describe('Initialization', function () { + it('Should succeed and initialize constants manager', async function () { + // manager is deployed by the initializer and its address is stored in the SFC + const manager: ConstantsManager = await ethers.getContractAt( + 'ConstantsManager', + await (await ethers.getContractAt('SFC', this.sfcProxy)).constsAddress(), + ); + expect(await manager.owner()).to.equal(this.owner); + expect(await manager.minSelfStake()).to.equal(500000n * BigInt(1e18)); + expect(await manager.maxDelegatedRatio()).to.equal(16n * BigInt(1e18)); + expect(await manager.validatorCommission()).to.equal((15n * BigInt(1e18)) / 100n); + expect(await manager.burntFeeShare()).to.equal((20n * BigInt(1e18)) / 100n); + expect(await manager.treasuryFeeShare()).to.equal((10n * BigInt(1e18)) / 100n); + expect(await manager.withdrawalPeriodEpochs()).to.equal(3); + expect(await manager.withdrawalPeriodTime()).to.equal(60 * 60 * 24 * 7); + expect(await manager.baseRewardPerSecond()).to.equal(2668658453701531600n); + expect(await manager.offlinePenaltyThresholdTime()).to.equal(5 * 24 * 60 * 60); + expect(await manager.offlinePenaltyThresholdBlocksNum()).to.equal(1000); + expect(await manager.targetGasPowerPerSecond()).to.equal(2000000); + expect(await manager.gasPriceBalancingCounterweight()).to.equal(3600); + expect(await manager.averageUptimeEpochWindow()).to.equal(100); + expect(await manager.minAverageUptime()).to.equal(0); + expect(await manager.issuedTokensRecipient()).to.equal(ethers.ZeroAddress); + }); + + it('Should succeed and initialize NodeDriver', async function () { + const nodeDriver: NodeDriver = await ethers.getContractAt('NodeDriver', this.nodeDriverProxy); + expect(await nodeDriver.owner()).to.equal(this.owner); + }); + + it('Should succeed and initialize NodeDriverAuth', async function () { + const nodeDriverAuth: NodeDriverAuth = await ethers.getContractAt('NodeDriverAuth', this.nodeDriverAuthProxy); + expect(await nodeDriverAuth.owner()).to.equal(this.owner); + }); + + it('Should succeed and initialize SFC', async function () { + const sfc: SFC = await ethers.getContractAt('SFC', this.sfcProxy); + expect(await sfc.owner()).to.equal(this.owner); + expect(await sfc.currentSealedEpoch()).to.equal(this.epoch); + expect(await sfc.totalSupply()).to.equal(this.totalSupply); + const [endTime, , , , ,] = await sfc.getEpochSnapshot(this.epoch); + expect(endTime).to.equal(await time.latest()); + }); + + it('Should revert when re-initializing SFC', async function () { + const sfc: SFC = await ethers.getContractAt('SFC', this.sfcProxy); + const consants = await (await ethers.getContractAt('SFC', this.sfcProxy)).constsAddress(); + await expect( + sfc.connect(this.user).initialize(this.epoch, this.totalSupply, this.nodeDriverAuthProxy, consants, this.owner), + ).to.be.revertedWithCustomError(sfc, 'InvalidInitialization'); + }); + + it('Should revert when re-initializing NodeDriver', async function () { + const nodeDriver: NodeDriver = await ethers.getContractAt('NodeDriver', this.nodeDriverProxy); + await expect( + nodeDriver.connect(this.user).initialize(this.nodeDriverAuthProxy, this.evmWriter, this.owner), + ).to.be.revertedWithCustomError(nodeDriver, 'InvalidInitialization'); + }); + + it('Should revert when re-initializing NodeDriverAuth', async function () { + const nodeDriverAuth: NodeDriverAuth = await ethers.getContractAt('NodeDriverAuth', this.nodeDriverAuthProxy); + await expect( + nodeDriverAuth.connect(this.user).initialize(this.sfcProxy, this.nodeDriverProxy, this.owner), + ).to.be.revertedWithCustomError(nodeDriverAuth, 'InvalidInitialization'); + }); + + it('Should revert when initializing SFC implementation directly', async function () { + const sfc: SFC = await ethers.getContractAt('SFC', this.sfc); + const consants = await (await ethers.getContractAt('SFC', this.sfcProxy)).constsAddress(); + await expect( + sfc.connect(this.user).initialize(this.epoch, this.totalSupply, this.nodeDriverAuthProxy, consants, this.owner), + ).to.be.revertedWithCustomError(sfc, 'InvalidInitialization'); + }); + + it('Should revert when initializing NodeDriver implementation directly', async function () { + const nodeDriver: NodeDriver = await ethers.getContractAt('NodeDriver', this.nodeDriver); + await expect( + nodeDriver.connect(this.user).initialize(this.nodeDriverAuthProxy, this.evmWriter, this.owner), + ).to.be.revertedWithCustomError(nodeDriver, 'InvalidInitialization'); + }); + + it('Should revert when initializing NodeDriverAuth implementation directly', async function () { + const nodeDriverAuth: NodeDriverAuth = await ethers.getContractAt('NodeDriverAuth', this.nodeDriverAuth); + await expect( + nodeDriverAuth.connect(this.user).initialize(this.sfcProxy, this.nodeDriverProxy, this.owner), + ).to.be.revertedWithCustomError(nodeDriverAuth, 'InvalidInitialization'); + }); + }); + + describe('Upgrade', function () { + it('Should revert when SFC upgrade made not by owner', async function () { + const sfc: SFC = await ethers.getContractAt('SFC', this.sfcProxy); + await expect( + sfc.connect(this.user).upgradeToAndCall(ethers.Wallet.createRandom(), '0x'), + ).to.be.revertedWithCustomError(sfc, 'OwnableUnauthorizedAccount'); + }); + + it('Should revert when NodeDriver upgrade made not by owner', async function () { + const nodeDriver: NodeDriver = await ethers.getContractAt('NodeDriver', this.nodeDriverProxy); + await expect( + nodeDriver.connect(this.user).upgradeToAndCall(ethers.Wallet.createRandom(), '0x'), + ).to.be.revertedWithCustomError(nodeDriver, 'OwnableUnauthorizedAccount'); + }); + + it('Should revert when NodeDriverAuth upgrade made not by owner', async function () { + const nodeDriverAuth: NodeDriverAuth = await ethers.getContractAt('NodeDriverAuth', this.nodeDriverAuthProxy); + await expect( + nodeDriverAuth.connect(this.user).upgradeToAndCall(ethers.Wallet.createRandom(), '0x'), + ).to.be.revertedWithCustomError(nodeDriverAuth, 'OwnableUnauthorizedAccount'); + }); + + it('Should revert when SFC upgrade made on implementation', async function () { + const sfc: SFC = await ethers.getContractAt('SFC', this.sfc); + await expect( + sfc.connect(this.user).upgradeToAndCall(ethers.Wallet.createRandom(), '0x'), + ).to.be.revertedWithCustomError(sfc, 'UUPSUnauthorizedCallContext'); + }); + + it('Should revert when NodeDriver upgrade made on implementation', async function () { + const nodeDriver: NodeDriver = await ethers.getContractAt('NodeDriver', this.nodeDriver); + await expect( + nodeDriver.connect(this.user).upgradeToAndCall(ethers.Wallet.createRandom(), '0x'), + ).to.be.revertedWithCustomError(nodeDriver, 'UUPSUnauthorizedCallContext'); + }); + + it('Should revert when NodeDriverAuth upgrade made on implementation', async function () { + const nodeDriverAuth: NodeDriverAuth = await ethers.getContractAt('NodeDriverAuth', this.nodeDriverAuth); + await expect( + nodeDriverAuth.connect(this.user).upgradeToAndCall(ethers.Wallet.createRandom(), '0x'), + ).to.be.revertedWithCustomError(nodeDriverAuth, 'UUPSUnauthorizedCallContext'); + }); + + it('Should should succeed and upgrade SFC', async function () { + const sfc: SFC = await ethers.getContractAt('SFC', this.sfcProxy); + const newSFC = await ethers.deployContract('SFC'); + await sfc.connect(this.owner).upgradeToAndCall(newSFC, '0x'); + + // check that the new implementation is used + const newImplementationAddress = await ethers.provider.getStorage( + sfc, + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', + ); + expect(ethers.AbiCoder.defaultAbiCoder().decode(['address'], newImplementationAddress)[0]).to.equal( + await newSFC.getAddress(), + ); + + // check that the new implementation has initialized status set + const initialized = await ethers.provider.getStorage( + newSFC, + '0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00', + ); + expect(initialized).to.equal('0x000000000000000000000000000000000000000000000000ffffffffffffffff'); + + // check that the proxy returns correct values + expect(await sfc.owner()).to.equal(this.owner); + expect(await sfc.currentSealedEpoch()).to.equal(this.epoch); + expect(await sfc.totalSupply()).to.equal(this.totalSupply); + + // should revert when trying to re-initialize + const consants = await (await ethers.getContractAt('SFC', this.sfcProxy)).constsAddress(); + await expect( + sfc.connect(this.user).initialize(this.epoch, this.totalSupply, this.nodeDriverAuthProxy, consants, this.owner), + ).to.be.revertedWithCustomError(sfc, 'InvalidInitialization'); + + // should revert when initializing implementation directly + await expect( + newSFC + .connect(this.user) + .initialize(this.epoch, this.totalSupply, this.nodeDriverAuthProxy, consants, this.owner), + ).to.be.revertedWithCustomError(newSFC, 'InvalidInitialization'); + }); + + it('Should should succeed and upgrade NodeDriver', async function () { + const nodeDriver: NodeDriver = await ethers.getContractAt('NodeDriver', this.nodeDriverProxy); + const newNodeDriver = await ethers.deployContract('NodeDriver'); + await nodeDriver.connect(this.owner).upgradeToAndCall(newNodeDriver, '0x'); + + // check that the new implementation is used + const newImplementationAddress = await ethers.provider.getStorage( + nodeDriver, + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', + ); + expect(ethers.AbiCoder.defaultAbiCoder().decode(['address'], newImplementationAddress)[0]).to.equal( + await newNodeDriver.getAddress(), + ); + + // check that the new implementation has initialized status set + const initialized = await ethers.provider.getStorage( + newNodeDriver, + '0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00', + ); + expect(initialized).to.equal('0x000000000000000000000000000000000000000000000000ffffffffffffffff'); + + // check that the proxy returns correct values + expect(await nodeDriver.owner()).to.equal(this.owner); + + // should revert when trying to re-initialize + await expect( + nodeDriver.connect(this.user).initialize(this.nodeDriverAuthProxy, this.evmWriter, this.owner), + ).to.be.revertedWithCustomError(nodeDriver, 'InvalidInitialization'); + + // should revert when initializing implementation directly + await expect( + newNodeDriver.connect(this.user).initialize(this.nodeDriverAuthProxy, this.evmWriter, this.owner), + ).to.be.revertedWithCustomError(newNodeDriver, 'InvalidInitialization'); + }); + + it('Should should succeed and upgrade NodeDriverAuth', async function () { + const nodeDriverAuth: NodeDriverAuth = await ethers.getContractAt('NodeDriverAuth', this.nodeDriverAuthProxy); + const newNodeDriverAuth = await ethers.deployContract('NodeDriverAuth'); + await nodeDriverAuth.connect(this.owner).upgradeToAndCall(newNodeDriverAuth, '0x'); + + // check that the new implementation is used + const newImplementationAddress = await ethers.provider.getStorage( + nodeDriverAuth, + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', + ); + expect(ethers.AbiCoder.defaultAbiCoder().decode(['address'], newImplementationAddress)[0]).to.equal( + await newNodeDriverAuth.getAddress(), + ); + + // check that the new implementation has initialized status set + const initialized = await ethers.provider.getStorage( + newNodeDriverAuth, + '0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00', + ); + expect(initialized).to.equal('0x000000000000000000000000000000000000000000000000ffffffffffffffff'); + + // check that the proxy returns correct values + expect(await nodeDriverAuth.owner()).to.equal(this.owner); + + // should revert when trying to re-initialize + await expect( + nodeDriverAuth.connect(this.user).initialize(this.sfcProxy, this.nodeDriverProxy, this.owner), + ).to.be.revertedWithCustomError(nodeDriverAuth, 'InvalidInitialization'); + + // should revert when initializing implementation directly + await expect( + newNodeDriverAuth.connect(this.user).initialize(this.sfcProxy, this.nodeDriverProxy, this.owner), + ).to.be.revertedWithCustomError(newNodeDriverAuth, 'InvalidInitialization'); + }); + }); +});