{"matchId":"30482354","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-06-03T01:53:19Z","creationBytecode":{"onchainBytecode":"0x6101206040523480156200001257600080fd5b5060405162002dd638038062002dd6833981016040819052620000359162000933565b8989878a8a8c6000036200004b57600062000051565b60408701515b60e08b01518686600362000066838262000ad3565b50600462000075828262000ad3565b50505083600014620000d057620000b0856200009385600a62000cb4565b6200009f908762000ccc565b620003b160201b6200100a1760201c565b620000be8460001962000ce6565b620000cc9060001962000d09565b6007555b6007546001600160a01b0390951660009081526005602052604090209490945560095550501515608052506200010f9050620001093390565b62000474565b8460e0015180156200013857508460200151806200012b575084515b806200013857508460c001515b806200015557508460e00151158015620001555750604082015115155b156200017457604051630c2a1c3360e21b815260040160405180910390fd5b846060015115620001ad578051600003620001ad5780516040516364824b8d60e01b815260048101919091526024015b60405180910390fd5b60128760ff161115620001d95760405163ca95039160e01b815260ff88166004820152602401620001a4565b84608001518015620001fa575084511580620001fa57506020810151600254115b156200021957604051635a8d424160e11b815260040160405180910390fd5b62000226858385620004c6565b6200023c866200056660201b620010c91760201c565b601080546001600160a01b0319166001600160a01b0385161790558151601155602082015160125560a0889052805160c052600b6200027c858262000ad3565b506001600160a01b03861660e090815260ff88166101009081528651600f805460208a015160408b015160608c015160808d015160a08e015160c08f0151998f015161ffff1990961697151561ff001916979097179315159097029290921763ffff00001916620100009115159190910263ff0000001916176301000000911515919091021761ffff60201b19166401000000009415159490940260ff60281b19169390931765010000000000921515929092029190911761ffff60301b191666010000000000009315159390930260ff60381b19169290921767010000000000000091151591909102179055600c62000377858262000ad3565b508051600d556020810151600e55336001600160a01b03871614620003a157620003a18662000580565b5050505050505050505062000d35565b6001600160a01b038216620004095760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401620001a4565b80600260008282546200041d919062000d1f565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60008360a0015115620004fa57620004e9826200056660201b620010c91760201c565b8251620004f7908262000d1f565b90505b8360c00151156200051957602083015162000516908262000d1f565b90505b8360e00151156200053857604083015162000535908262000d1f565b90505b6107d08111156200056057604051633e474e0d60e01b815260048101829052602401620001a4565b50505050565b8060601b6200057d5763d92e233d6000526004601cfd5b50565b6200058a620005a5565b6200057d816200060360201b620010df1760201c565b505050565b600a546001600160a01b03163314620006015760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620001a4565b565b6200060d620005a5565b6001600160a01b038116620006745760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401620001a4565b6200057d8162000474565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620006c057620006c06200067f565b604052919050565b600082601f830112620006da57600080fd5b81516001600160401b03811115620006f657620006f66200067f565b60206200070c601f8301601f1916820162000695565b82815285828487010111156200072157600080fd5b60005b838110156200074157858101830151828201840152820162000724565b506000928101909101919091529392505050565b805160ff811681146200076757600080fd5b919050565b80516001600160a01b03811681146200076757600080fd5b805180151581146200076757600080fd5b6000610100808385031215620007aa57600080fd5b604051908101906001600160401b0382118183101715620007cf57620007cf6200067f565b81604052809250620007e18462000784565b8152620007f16020850162000784565b6020820152620008046040850162000784565b6040820152620008176060850162000784565b60608201526200082a6080850162000784565b60808201526200083d60a0850162000784565b60a08201526200085060c0850162000784565b60c08201526200086360e0850162000784565b60e0820152505092915050565b600082601f8301126200088257600080fd5b604051606081016001600160401b0381118282101715620008a757620008a76200067f565b604052806060840185811115620008bd57600080fd5b845b81811015620008d9578051835260209283019201620008bf565b509195945050505050565b600082601f830112620008f657600080fd5b604080519081016001600160401b03811182821017156200091b576200091b6200067f565b8060405250806040840185811115620008bd57600080fd5b6000806000806000806000806000806102808b8d0312156200095457600080fd5b8a516001600160401b03808211156200096c57600080fd5b6200097a8e838f01620006c8565b9b5060208d01519150808211156200099157600080fd5b6200099f8e838f01620006c8565b9a5060408d01519950620009b660608e0162000755565b9850620009c660808e016200076c565b9750620009d78e60a08f0162000795565b96506101a08d0151915080821115620009ef57600080fd5b50620009fe8d828e01620006c8565b94505062000a106101c08c016200076c565b925062000a228c6101e08d0162000870565b915062000a348c6102408d01620008e4565b90509295989b9194979a5092959850565b600181811c9082168062000a5a57607f821691505b60208210810362000a7b57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620005a057600081815260208120601f850160051c8101602086101562000aaa5750805b601f850160051c820191505b8181101562000acb5782815560010162000ab6565b505050505050565b81516001600160401b0381111562000aef5762000aef6200067f565b62000b078162000b00845462000a45565b8462000a81565b602080601f83116001811462000b3f576000841562000b265750858301515b600019600386901b1c1916600185901b17855562000acb565b600085815260208120601f198616915b8281101562000b705788860151825594840194600190910190840162000b4f565b508582101562000b8f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b600181815b8085111562000bf657816000190482111562000bda5762000bda62000b9f565b8085161562000be857918102915b93841c939080029062000bba565b509250929050565b60008262000c0f5750600162000cae565b8162000c1e5750600062000cae565b816001811462000c37576002811462000c425762000c62565b600191505062000cae565b60ff84111562000c565762000c5662000b9f565b50506001821b62000cae565b5060208310610133831016604e8410600b841016171562000c87575081810a62000cae565b62000c93838362000bb5565b806000190482111562000caa5762000caa62000b9f565b0290505b92915050565b600062000cc560ff84168362000bfe565b9392505050565b808202811582820484141762000cae5762000cae62000b9f565b60008262000d0457634e487b7160e01b600052601260045260246000fd5b500690565b8181038181111562000cae5762000cae62000b9f565b8082018082111562000cae5762000cae62000b9f565b60805160a05160c05160e0516101005161203962000d9d60003960006103b3015260006104cc01526000610519015260006103e2015260008181610b1c0152818161138a0152818161143c015281816114c10152818161152a0152611a9301526120396000f3fe608060405234801561001057600080fd5b50600436106102e95760003560e01c8063883356d911610191578063af465a27116100e3578063de0060ca11610097578063f820f56711610071578063f820f56714610625578063f91f825d14610636578063ffa1ad741461064957600080fd5b8063de0060ca146105ec578063f19c4e3b146105ff578063f2fde38b1461061257600080fd5b8063d48e4127116100c8578063d48e412714610597578063d8f67851146105a0578063dd62ed3e146105b357600080fd5b8063af465a271461057c578063b7bda68f1461058457600080fd5b80639703a19d11610145578063a476df611161011f578063a476df611461054e578063a9059cbb14610561578063a9d866851461057457600080fd5b80639703a19d1461050b578063a32f697614610514578063a457c2d71461053b57600080fd5b80638dac7191116101765780638dac7191146104c75780638e8c10a2146104ee57806395d89b411461050357600080fd5b8063883356d9146104925780638da5cb5b146104a257600080fd5b8063313ce5671161024a57806346b45af7116101fe5780635a3990ce116101d85780635a3990ce1461046557806370a0823114610477578063715018a61461048a57600080fd5b806346b45af71461043d5780634ac0bc3214610448578063542e96671461045c57600080fd5b8063395093511161022f578063395093511461040457806340c10f191461041757806342966c681461042a57600080fd5b8063313ce567146103ac578063378dc3dc146103dd57600080fd5b806323b872dd116102a15780632d838119116102865780632d8381191461037a5780632e0ee48e1461038d5780632fa782eb146103a357600080fd5b806323b872dd1461035e5780632ab4d0521461037157600080fd5b806306fdde03116102d257806306fdde0314610321578063095ea7b31461032957806318160ddd1461034c57600080fd5b806302252c4d146102ee578063044ab74e14610303575b600080fd5b6103016102fc366004611c4d565b610685565b005b61030b610747565b6040516103189190611c66565b60405180910390f35b61030b6107d5565b61033c610337366004611ccb565b610867565b6040519015158152602001610318565b6002545b604051908152602001610318565b61033c61036c366004611cf5565b610881565b610350600e5481565b610350610388366004611c4d565b610953565b600f54670100000000000000900460ff1661033c565b61035060115481565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610318565b6103507f000000000000000000000000000000000000000000000000000000000000000081565b61033c610412366004611ccb565b6109ae565b610301610425366004611ccb565b6109ed565b610301610438366004611c4d565b610adb565b600f5460ff1661033c565b600f5465010000000000900460ff1661033c565b61035060125481565b600f546301000000900460ff1661033c565b610350610485366004611d31565b610b18565b610301610b85565b600f54610100900460ff1661033c565b600a546001600160a01b03165b6040516001600160a01b039091168152602001610318565b6104af7f000000000000000000000000000000000000000000000000000000000000000081565b600f546601000000000000900460ff1661033c565b61030b610b97565b61035060095481565b6103507f000000000000000000000000000000000000000000000000000000000000000081565b61033c610549366004611ccb565b610ba6565b61030161055c366004611d62565b610c5b565b61033c61056f366004611ccb565b610ce1565b61030b610dac565b610350610db9565b6010546104af906001600160a01b031681565b610350600d5481565b6103016105ae366004611c4d565b610dc9565b6103506105c1366004611e13565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b600f54640100000000900460ff1661033c565b61030161060d366004611ccb565b610e90565b610301610620366004611d31565b610f8c565b600f5462010000900460ff1661033c565b610301610644366004611c4d565b610f9d565b61030b6040518060400160405280600881526020017f646566695f765f3300000000000000000000000000000000000000000000000081525081565b61068d61116c565b600f546301000000900460ff166106d0576040517f6273340f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d54811161070b576040517fa43d2d7600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d8190556040518181527f2905481c6fd1a037492016c4760435a52203d82a6f34dc3de40f464c1bf42d59906020015b60405180910390a150565b600c805461075490611e46565b80601f016020809104026020016040519081016040528092919081815260200182805461078090611e46565b80156107cd5780601f106107a2576101008083540402835291602001916107cd565b820191906000526020600020905b8154815290600101906020018083116107b057829003601f168201915b505050505081565b6060600380546107e490611e46565b80601f016020809104026020016040519081016040528092919081815260200182805461081090611e46565b801561085d5780601f106108325761010080835404028352916020019161085d565b820191906000526020600020905b81548152906001019060200180831161084057829003601f168201915b5050505050905090565b6000336108758185856111c6565b60019150505b92915050565b60008061088e858461131e565b9050600061089b84611361565b90506000816108aa8487611e96565b6108b49190611e96565b600f549091506301000000900460ff161561090f57600d54816108d688610b18565b6108e09190611ea9565b111561090f5760405163f6202a8f60e01b81526001600160a01b03871660048201526024015b60405180910390fd5b821561092d5760105461092d9088906001600160a01b031685611388565b811561093d5761093d878361143a565b610948878783611483565b979650505050505050565b6000600754821115610991576040517fc91fa8bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061099b61149c565b90506109a78184611ebc565b9392505050565b3360008181526001602090815260408083206001600160a01b038716845290915281205490919061087590829086906109e8908790611ea9565b6111c6565b6109f561116c565b600f5460ff16610a1857604051630732158d60e31b815260040160405180910390fd5b600f546301000000900460ff1615610a6b57600d5481610a3784610b18565b610a419190611ea9565b1115610a6b5760405163f6202a8f60e01b81526001600160a01b0383166004820152602401610906565b600f54640100000000900460ff1615610acd57600e5481610a8b60025490565b610a959190611ea9565b1115610acd576040517f44ea8ea500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ad782826114bf565b5050565b610ae361116c565b600f54610100900460ff16610b0b57604051636cb5913960e01b815260040160405180910390fd5b610b15338261143a565b50565b60007f000000000000000000000000000000000000000000000000000000000000000015610b62576001600160a01b03821660009081526005602052604090205461087b90610953565b6001600160a01b03821660009081526020819052604090205461087b565b919050565b610b8d61116c565b610b95611508565b565b6060600480546107e490611e46565b3360008181526001602090815260408083206001600160a01b038716845290915281205490919083811015610c435760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610906565b610c5082868684036111c6565b506001949350505050565b610c6361116c565b600f5462010000900460ff16610ca5576040517f70a43fce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c610cb18282611f2c565b507f4456a0b562609d67398ddb488f136db285cd3c92343e0a7ba684925669237ade8160405161073c9190611c66565b600080610cee338461131e565b90506000610cfb84611361565b9050600081610d0a8487611e96565b610d149190611e96565b600f549091506301000000900460ff1615610d6a57600d5481610d3688610b18565b610d409190611ea9565b1115610d6a5760405163f6202a8f60e01b81526001600160a01b0387166004820152602401610906565b8215610d8857601054610d889033906001600160a01b031685611388565b8115610d9857610d98338361143a565b610da2868261151a565b9695505050505050565b600b805461075490611e46565b6000610dc460025490565b905090565b610dd161116c565b600f546601000000000000900460ff16610e17576040517fcd9e529800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081600954601254610e2a9190611ea9565b610e349190611ea9565b90506107d0811115610e5c57604051633e474e0d60e01b815260048101829052602401610906565b601282905560405182907fc1ff65ee907dc079b64ed9913d53f4bd593bd6ebd9b2a2708db2916d49e17ec390600090a25050565b610e9861116c565b600f5465010000000000900460ff16610edd576040517fc8a478a500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081600954601254610ef09190611ea9565b610efa9190611ea9565b90506107d0811115610f2257604051633e474e0d60e01b815260048101829052602401610906565b610f2b836110c9565b6010805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03851690811790915560118390556040518391907facc44e32fd5ca4240f6dbe6e8cf4eb49349c17c5ce5f80f1919a9c97b50d398a90600090a3505050565b610f9461116c565b610b15816110df565b610fa561116c565b600f54670100000000000000900460ff16610fd357604051630800e34b60e41b815260040160405180910390fd5b610fdc81611528565b60405181907f76e1296412dac7b50002658bf9aab02d0cfe366f373222d5c14d0168ee8199e390600090a250565b6001600160a01b0382166110605760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610906565b80600260008282546110729190611ea9565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b8060601b610b155763d92e233d6000526004601cfd5b6110e761116c565b6001600160a01b0381166111635760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610906565b610b158161156b565b600a546001600160a01b03163314610b955760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610906565b6001600160a01b0383166112415760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b0382166112bd5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b600060115460001415801561134157506010546001600160a01b03848116911614155b1561087b57612710601154836113579190611fec565b6109a79190611ebc565b6000601254600014610b80576127106012548361137e9190611fec565b61087b9190611ebc565b7f00000000000000000000000000000000000000000000000000000000000000001561142f57801561142a5760006113be61149c565b905060006113cc8284611fec565b90506113da858583846115ca565b836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161141f91815260200190565b60405180910390a350505b505050565b61142a8383836116ad565b7f00000000000000000000000000000000000000000000000000000000000000001561147957604051636cb5913960e01b815260040160405180910390fd5b610ad7828261189c565b600033611491858285611a05565b610c50858585611a91565b60008060006114a9611b0e565b90925090506114b88183611ebc565b9250505090565b7f0000000000000000000000000000000000000000000000000000000000000000156114fe57604051630732158d60e31b815260040160405180910390fd5b610ad7828261100a565b61151061116c565b610b95600061156b565b600033610875818585611a91565b7f000000000000000000000000000000000000000000000000000000000000000061156657604051630800e34b60e41b815260040160405180910390fd5b600955565b600a80546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b03841660009081526005602052604090205482811015611636576040517fe450d38c0000000000000000000000000000000000000000000000000000000081526001600160a01b03851660048201526024810182905260448101849052606401610906565b6001600160a01b03851660009081526005602052604090205461165a908490611e96565b6001600160a01b03808716600090815260056020526040808220939093559086168152205461168a908390611ea9565b6001600160a01b0390941660009081526005602052604090209390935550505050565b6001600160a01b0383166117295760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b0382166117a55760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b038316600090815260208190526040902054818110156118345760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35b50505050565b6001600160a01b0382166119185760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b038216600090815260208190526040902054818110156119a75760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146118965781811015611a845760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610906565b61189684848484036111c6565b7f00000000000000000000000000000000000000000000000000000000000000001561142f57611ac0836110c9565b611ac9826110c9565b80600003611b03576040517f76c4f5b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61142a838383611b24565b600080600754611b1c610db9565b915091509091565b6000611b2f82611bcb565b90506000611b3d8284611e96565b90506000806000611b4f868686611bde565b92509250925085600014611bc157611b69888885846115ca565b611b738286611c27565b866001600160a01b0316886001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef88604051611bb891815260200190565b60405180910390a35b5050505050505050565b60006127106009548361137e9190611fec565b600080600080611bec61149c565b90506000611bfa8289611fec565b90506000611c088389611fec565b90506000611c168489611fec565b929a91995091975095505050505050565b81600754611c359190611e96565b600755600854611c46908290611ea9565b6008555050565b600060208284031215611c5f57600080fd5b5035919050565b600060208083528351808285015260005b81811015611c9357858101830151858201604001528201611c77565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114610b8057600080fd5b60008060408385031215611cde57600080fd5b611ce783611cb4565b946020939093013593505050565b600080600060608486031215611d0a57600080fd5b611d1384611cb4565b9250611d2160208501611cb4565b9150604084013590509250925092565b600060208284031215611d4357600080fd5b6109a782611cb4565b634e487b7160e01b600052604160045260246000fd5b600060208284031215611d7457600080fd5b813567ffffffffffffffff80821115611d8c57600080fd5b818401915084601f830112611da057600080fd5b813581811115611db257611db2611d4c565b604051601f8201601f19908116603f01168101908382118183101715611dda57611dda611d4c565b81604052828152876020848701011115611df357600080fd5b826020860160208301376000928101602001929092525095945050505050565b60008060408385031215611e2657600080fd5b611e2f83611cb4565b9150611e3d60208401611cb4565b90509250929050565b600181811c90821680611e5a57607f821691505b602082108103611e7a57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561087b5761087b611e80565b8082018082111561087b5761087b611e80565b600082611ed957634e487b7160e01b600052601260045260246000fd5b500490565b601f82111561142a57600081815260208120601f850160051c81016020861015611f055750805b601f850160051c820191505b81811015611f2457828155600101611f11565b505050505050565b815167ffffffffffffffff811115611f4657611f46611d4c565b611f5a81611f548454611e46565b84611ede565b602080601f831160018114611f8f5760008415611f775750858301515b600019600386901b1c1916600185901b178555611f24565b600085815260208120601f198616915b82811015611fbe57888601518255948401946001909101908401611f9f565b5085821015611fdc5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b808202811582820484141761087b5761087b611e8056fea2646970667358221220f0883b06564851f25c2214f07da7f7c972f341f687d3de12c8903d945027bfe064736f6c63430008110033000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000000000000000000000000000000000003f00de810000000000000000000000000000000000000000000000000000000000000012000000000000000000000000157ae92276501b73b1a17d226bb89875d6eaafd1000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000157ae92276501b73b1a17d226bb89875d6eaafd10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000194e494c414d205265736f75726365732d204d696e64576176650000000000000000000000000000000000000000000000000000000000000000000000000000044e494c41000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","recompiledBytecode":"0x6101206040523480156200001257600080fd5b5060405162002dd638038062002dd6833981016040819052620000359162000933565b8989878a8a8c6000036200004b57600062000051565b60408701515b60e08b01518686600362000066838262000ad3565b50600462000075828262000ad3565b50505083600014620000d057620000b0856200009385600a62000cb4565b6200009f908762000ccc565b620003b160201b6200100a1760201c565b620000be8460001962000ce6565b620000cc9060001962000d09565b6007555b6007546001600160a01b0390951660009081526005602052604090209490945560095550501515608052506200010f9050620001093390565b62000474565b8460e0015180156200013857508460200151806200012b575084515b806200013857508460c001515b806200015557508460e00151158015620001555750604082015115155b156200017457604051630c2a1c3360e21b815260040160405180910390fd5b846060015115620001ad578051600003620001ad5780516040516364824b8d60e01b815260048101919091526024015b60405180910390fd5b60128760ff161115620001d95760405163ca95039160e01b815260ff88166004820152602401620001a4565b84608001518015620001fa575084511580620001fa57506020810151600254115b156200021957604051635a8d424160e11b815260040160405180910390fd5b62000226858385620004c6565b6200023c866200056660201b620010c91760201c565b601080546001600160a01b0319166001600160a01b0385161790558151601155602082015160125560a0889052805160c052600b6200027c858262000ad3565b506001600160a01b03861660e090815260ff88166101009081528651600f805460208a015160408b015160608c015160808d015160a08e015160c08f0151998f015161ffff1990961697151561ff001916979097179315159097029290921763ffff00001916620100009115159190910263ff0000001916176301000000911515919091021761ffff60201b19166401000000009415159490940260ff60281b19169390931765010000000000921515929092029190911761ffff60301b191666010000000000009315159390930260ff60381b19169290921767010000000000000091151591909102179055600c62000377858262000ad3565b508051600d556020810151600e55336001600160a01b03871614620003a157620003a18662000580565b5050505050505050505062000d35565b6001600160a01b038216620004095760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401620001a4565b80600260008282546200041d919062000d1f565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60008360a0015115620004fa57620004e9826200056660201b620010c91760201c565b8251620004f7908262000d1f565b90505b8360c00151156200051957602083015162000516908262000d1f565b90505b8360e00151156200053857604083015162000535908262000d1f565b90505b6107d08111156200056057604051633e474e0d60e01b815260048101829052602401620001a4565b50505050565b8060601b6200057d5763d92e233d6000526004601cfd5b50565b6200058a620005a5565b6200057d816200060360201b620010df1760201c565b505050565b600a546001600160a01b03163314620006015760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620001a4565b565b6200060d620005a5565b6001600160a01b038116620006745760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401620001a4565b6200057d8162000474565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620006c057620006c06200067f565b604052919050565b600082601f830112620006da57600080fd5b81516001600160401b03811115620006f657620006f66200067f565b60206200070c601f8301601f1916820162000695565b82815285828487010111156200072157600080fd5b60005b838110156200074157858101830151828201840152820162000724565b506000928101909101919091529392505050565b805160ff811681146200076757600080fd5b919050565b80516001600160a01b03811681146200076757600080fd5b805180151581146200076757600080fd5b6000610100808385031215620007aa57600080fd5b604051908101906001600160401b0382118183101715620007cf57620007cf6200067f565b81604052809250620007e18462000784565b8152620007f16020850162000784565b6020820152620008046040850162000784565b6040820152620008176060850162000784565b60608201526200082a6080850162000784565b60808201526200083d60a0850162000784565b60a08201526200085060c0850162000784565b60c08201526200086360e0850162000784565b60e0820152505092915050565b600082601f8301126200088257600080fd5b604051606081016001600160401b0381118282101715620008a757620008a76200067f565b604052806060840185811115620008bd57600080fd5b845b81811015620008d9578051835260209283019201620008bf565b509195945050505050565b600082601f830112620008f657600080fd5b604080519081016001600160401b03811182821017156200091b576200091b6200067f565b8060405250806040840185811115620008bd57600080fd5b6000806000806000806000806000806102808b8d0312156200095457600080fd5b8a516001600160401b03808211156200096c57600080fd5b6200097a8e838f01620006c8565b9b5060208d01519150808211156200099157600080fd5b6200099f8e838f01620006c8565b9a5060408d01519950620009b660608e0162000755565b9850620009c660808e016200076c565b9750620009d78e60a08f0162000795565b96506101a08d0151915080821115620009ef57600080fd5b50620009fe8d828e01620006c8565b94505062000a106101c08c016200076c565b925062000a228c6101e08d0162000870565b915062000a348c6102408d01620008e4565b90509295989b9194979a5092959850565b600181811c9082168062000a5a57607f821691505b60208210810362000a7b57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620005a057600081815260208120601f850160051c8101602086101562000aaa5750805b601f850160051c820191505b8181101562000acb5782815560010162000ab6565b505050505050565b81516001600160401b0381111562000aef5762000aef6200067f565b62000b078162000b00845462000a45565b8462000a81565b602080601f83116001811462000b3f576000841562000b265750858301515b600019600386901b1c1916600185901b17855562000acb565b600085815260208120601f198616915b8281101562000b705788860151825594840194600190910190840162000b4f565b508582101562000b8f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b600181815b8085111562000bf657816000190482111562000bda5762000bda62000b9f565b8085161562000be857918102915b93841c939080029062000bba565b509250929050565b60008262000c0f5750600162000cae565b8162000c1e5750600062000cae565b816001811462000c37576002811462000c425762000c62565b600191505062000cae565b60ff84111562000c565762000c5662000b9f565b50506001821b62000cae565b5060208310610133831016604e8410600b841016171562000c87575081810a62000cae565b62000c93838362000bb5565b806000190482111562000caa5762000caa62000b9f565b0290505b92915050565b600062000cc560ff84168362000bfe565b9392505050565b808202811582820484141762000cae5762000cae62000b9f565b60008262000d0457634e487b7160e01b600052601260045260246000fd5b500690565b8181038181111562000cae5762000cae62000b9f565b8082018082111562000cae5762000cae62000b9f565b60805160a05160c05160e0516101005161203962000d9d60003960006103b3015260006104cc01526000610519015260006103e2015260008181610b1c0152818161138a0152818161143c015281816114c10152818161152a0152611a9301526120396000f3fe608060405234801561001057600080fd5b50600436106102e95760003560e01c8063883356d911610191578063af465a27116100e3578063de0060ca11610097578063f820f56711610071578063f820f56714610625578063f91f825d14610636578063ffa1ad741461064957600080fd5b8063de0060ca146105ec578063f19c4e3b146105ff578063f2fde38b1461061257600080fd5b8063d48e4127116100c8578063d48e412714610597578063d8f67851146105a0578063dd62ed3e146105b357600080fd5b8063af465a271461057c578063b7bda68f1461058457600080fd5b80639703a19d11610145578063a476df611161011f578063a476df611461054e578063a9059cbb14610561578063a9d866851461057457600080fd5b80639703a19d1461050b578063a32f697614610514578063a457c2d71461053b57600080fd5b80638dac7191116101765780638dac7191146104c75780638e8c10a2146104ee57806395d89b411461050357600080fd5b8063883356d9146104925780638da5cb5b146104a257600080fd5b8063313ce5671161024a57806346b45af7116101fe5780635a3990ce116101d85780635a3990ce1461046557806370a0823114610477578063715018a61461048a57600080fd5b806346b45af71461043d5780634ac0bc3214610448578063542e96671461045c57600080fd5b8063395093511161022f578063395093511461040457806340c10f191461041757806342966c681461042a57600080fd5b8063313ce567146103ac578063378dc3dc146103dd57600080fd5b806323b872dd116102a15780632d838119116102865780632d8381191461037a5780632e0ee48e1461038d5780632fa782eb146103a357600080fd5b806323b872dd1461035e5780632ab4d0521461037157600080fd5b806306fdde03116102d257806306fdde0314610321578063095ea7b31461032957806318160ddd1461034c57600080fd5b806302252c4d146102ee578063044ab74e14610303575b600080fd5b6103016102fc366004611c4d565b610685565b005b61030b610747565b6040516103189190611c66565b60405180910390f35b61030b6107d5565b61033c610337366004611ccb565b610867565b6040519015158152602001610318565b6002545b604051908152602001610318565b61033c61036c366004611cf5565b610881565b610350600e5481565b610350610388366004611c4d565b610953565b600f54670100000000000000900460ff1661033c565b61035060115481565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610318565b6103507f000000000000000000000000000000000000000000000000000000000000000081565b61033c610412366004611ccb565b6109ae565b610301610425366004611ccb565b6109ed565b610301610438366004611c4d565b610adb565b600f5460ff1661033c565b600f5465010000000000900460ff1661033c565b61035060125481565b600f546301000000900460ff1661033c565b610350610485366004611d31565b610b18565b610301610b85565b600f54610100900460ff1661033c565b600a546001600160a01b03165b6040516001600160a01b039091168152602001610318565b6104af7f000000000000000000000000000000000000000000000000000000000000000081565b600f546601000000000000900460ff1661033c565b61030b610b97565b61035060095481565b6103507f000000000000000000000000000000000000000000000000000000000000000081565b61033c610549366004611ccb565b610ba6565b61030161055c366004611d62565b610c5b565b61033c61056f366004611ccb565b610ce1565b61030b610dac565b610350610db9565b6010546104af906001600160a01b031681565b610350600d5481565b6103016105ae366004611c4d565b610dc9565b6103506105c1366004611e13565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b600f54640100000000900460ff1661033c565b61030161060d366004611ccb565b610e90565b610301610620366004611d31565b610f8c565b600f5462010000900460ff1661033c565b610301610644366004611c4d565b610f9d565b61030b6040518060400160405280600881526020017f646566695f765f3300000000000000000000000000000000000000000000000081525081565b61068d61116c565b600f546301000000900460ff166106d0576040517f6273340f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d54811161070b576040517fa43d2d7600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d8190556040518181527f2905481c6fd1a037492016c4760435a52203d82a6f34dc3de40f464c1bf42d59906020015b60405180910390a150565b600c805461075490611e46565b80601f016020809104026020016040519081016040528092919081815260200182805461078090611e46565b80156107cd5780601f106107a2576101008083540402835291602001916107cd565b820191906000526020600020905b8154815290600101906020018083116107b057829003601f168201915b505050505081565b6060600380546107e490611e46565b80601f016020809104026020016040519081016040528092919081815260200182805461081090611e46565b801561085d5780601f106108325761010080835404028352916020019161085d565b820191906000526020600020905b81548152906001019060200180831161084057829003601f168201915b5050505050905090565b6000336108758185856111c6565b60019150505b92915050565b60008061088e858461131e565b9050600061089b84611361565b90506000816108aa8487611e96565b6108b49190611e96565b600f549091506301000000900460ff161561090f57600d54816108d688610b18565b6108e09190611ea9565b111561090f5760405163f6202a8f60e01b81526001600160a01b03871660048201526024015b60405180910390fd5b821561092d5760105461092d9088906001600160a01b031685611388565b811561093d5761093d878361143a565b610948878783611483565b979650505050505050565b6000600754821115610991576040517fc91fa8bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061099b61149c565b90506109a78184611ebc565b9392505050565b3360008181526001602090815260408083206001600160a01b038716845290915281205490919061087590829086906109e8908790611ea9565b6111c6565b6109f561116c565b600f5460ff16610a1857604051630732158d60e31b815260040160405180910390fd5b600f546301000000900460ff1615610a6b57600d5481610a3784610b18565b610a419190611ea9565b1115610a6b5760405163f6202a8f60e01b81526001600160a01b0383166004820152602401610906565b600f54640100000000900460ff1615610acd57600e5481610a8b60025490565b610a959190611ea9565b1115610acd576040517f44ea8ea500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ad782826114bf565b5050565b610ae361116c565b600f54610100900460ff16610b0b57604051636cb5913960e01b815260040160405180910390fd5b610b15338261143a565b50565b60007f000000000000000000000000000000000000000000000000000000000000000015610b62576001600160a01b03821660009081526005602052604090205461087b90610953565b6001600160a01b03821660009081526020819052604090205461087b565b919050565b610b8d61116c565b610b95611508565b565b6060600480546107e490611e46565b3360008181526001602090815260408083206001600160a01b038716845290915281205490919083811015610c435760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610906565b610c5082868684036111c6565b506001949350505050565b610c6361116c565b600f5462010000900460ff16610ca5576040517f70a43fce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c610cb18282611f2c565b507f4456a0b562609d67398ddb488f136db285cd3c92343e0a7ba684925669237ade8160405161073c9190611c66565b600080610cee338461131e565b90506000610cfb84611361565b9050600081610d0a8487611e96565b610d149190611e96565b600f549091506301000000900460ff1615610d6a57600d5481610d3688610b18565b610d409190611ea9565b1115610d6a5760405163f6202a8f60e01b81526001600160a01b0387166004820152602401610906565b8215610d8857601054610d889033906001600160a01b031685611388565b8115610d9857610d98338361143a565b610da2868261151a565b9695505050505050565b600b805461075490611e46565b6000610dc460025490565b905090565b610dd161116c565b600f546601000000000000900460ff16610e17576040517fcd9e529800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081600954601254610e2a9190611ea9565b610e349190611ea9565b90506107d0811115610e5c57604051633e474e0d60e01b815260048101829052602401610906565b601282905560405182907fc1ff65ee907dc079b64ed9913d53f4bd593bd6ebd9b2a2708db2916d49e17ec390600090a25050565b610e9861116c565b600f5465010000000000900460ff16610edd576040517fc8a478a500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081600954601254610ef09190611ea9565b610efa9190611ea9565b90506107d0811115610f2257604051633e474e0d60e01b815260048101829052602401610906565b610f2b836110c9565b6010805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03851690811790915560118390556040518391907facc44e32fd5ca4240f6dbe6e8cf4eb49349c17c5ce5f80f1919a9c97b50d398a90600090a3505050565b610f9461116c565b610b15816110df565b610fa561116c565b600f54670100000000000000900460ff16610fd357604051630800e34b60e41b815260040160405180910390fd5b610fdc81611528565b60405181907f76e1296412dac7b50002658bf9aab02d0cfe366f373222d5c14d0168ee8199e390600090a250565b6001600160a01b0382166110605760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610906565b80600260008282546110729190611ea9565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b8060601b610b155763d92e233d6000526004601cfd5b6110e761116c565b6001600160a01b0381166111635760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610906565b610b158161156b565b600a546001600160a01b03163314610b955760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610906565b6001600160a01b0383166112415760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b0382166112bd5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b600060115460001415801561134157506010546001600160a01b03848116911614155b1561087b57612710601154836113579190611fec565b6109a79190611ebc565b6000601254600014610b80576127106012548361137e9190611fec565b61087b9190611ebc565b7f00000000000000000000000000000000000000000000000000000000000000001561142f57801561142a5760006113be61149c565b905060006113cc8284611fec565b90506113da858583846115ca565b836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161141f91815260200190565b60405180910390a350505b505050565b61142a8383836116ad565b7f00000000000000000000000000000000000000000000000000000000000000001561147957604051636cb5913960e01b815260040160405180910390fd5b610ad7828261189c565b600033611491858285611a05565b610c50858585611a91565b60008060006114a9611b0e565b90925090506114b88183611ebc565b9250505090565b7f0000000000000000000000000000000000000000000000000000000000000000156114fe57604051630732158d60e31b815260040160405180910390fd5b610ad7828261100a565b61151061116c565b610b95600061156b565b600033610875818585611a91565b7f000000000000000000000000000000000000000000000000000000000000000061156657604051630800e34b60e41b815260040160405180910390fd5b600955565b600a80546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b03841660009081526005602052604090205482811015611636576040517fe450d38c0000000000000000000000000000000000000000000000000000000081526001600160a01b03851660048201526024810182905260448101849052606401610906565b6001600160a01b03851660009081526005602052604090205461165a908490611e96565b6001600160a01b03808716600090815260056020526040808220939093559086168152205461168a908390611ea9565b6001600160a01b0390941660009081526005602052604090209390935550505050565b6001600160a01b0383166117295760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b0382166117a55760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b038316600090815260208190526040902054818110156118345760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35b50505050565b6001600160a01b0382166119185760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b038216600090815260208190526040902054818110156119a75760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146118965781811015611a845760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610906565b61189684848484036111c6565b7f00000000000000000000000000000000000000000000000000000000000000001561142f57611ac0836110c9565b611ac9826110c9565b80600003611b03576040517f76c4f5b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61142a838383611b24565b600080600754611b1c610db9565b915091509091565b6000611b2f82611bcb565b90506000611b3d8284611e96565b90506000806000611b4f868686611bde565b92509250925085600014611bc157611b69888885846115ca565b611b738286611c27565b866001600160a01b0316886001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef88604051611bb891815260200190565b60405180910390a35b5050505050505050565b60006127106009548361137e9190611fec565b600080600080611bec61149c565b90506000611bfa8289611fec565b90506000611c088389611fec565b90506000611c168489611fec565b929a91995091975095505050505050565b81600754611c359190611e96565b600755600854611c46908290611ea9565b6008555050565b600060208284031215611c5f57600080fd5b5035919050565b600060208083528351808285015260005b81811015611c9357858101830151858201604001528201611c77565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114610b8057600080fd5b60008060408385031215611cde57600080fd5b611ce783611cb4565b946020939093013593505050565b600080600060608486031215611d0a57600080fd5b611d1384611cb4565b9250611d2160208501611cb4565b9150604084013590509250925092565b600060208284031215611d4357600080fd5b6109a782611cb4565b634e487b7160e01b600052604160045260246000fd5b600060208284031215611d7457600080fd5b813567ffffffffffffffff80821115611d8c57600080fd5b818401915084601f830112611da057600080fd5b813581811115611db257611db2611d4c565b604051601f8201601f19908116603f01168101908382118183101715611dda57611dda611d4c565b81604052828152876020848701011115611df357600080fd5b826020860160208301376000928101602001929092525095945050505050565b60008060408385031215611e2657600080fd5b611e2f83611cb4565b9150611e3d60208401611cb4565b90509250929050565b600181811c90821680611e5a57607f821691505b602082108103611e7a57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561087b5761087b611e80565b8082018082111561087b5761087b611e80565b600082611ed957634e487b7160e01b600052601260045260246000fd5b500490565b601f82111561142a57600081815260208120601f850160051c81016020861015611f055750805b601f850160051c820191505b81811015611f2457828155600101611f11565b505050505050565b815167ffffffffffffffff811115611f4657611f46611d4c565b611f5a81611f548454611e46565b84611ede565b602080601f831160018114611f8f5760008415611f775750858301515b600019600386901b1c1916600185901b178555611f24565b600085815260208120601f198616915b82811015611fbe57888601518255948401946001909101908401611f9f565b5085821015611fdc5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b808202811582820484141761087b5761087b611e8056fea2646970667358221220f0883b06564851f25c2214f07da7f7c972f341f687d3de12c8903d945027bfe064736f6c63430008110033","sourceMap":"395:14391:5:-:0;;;3119:2064;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3470:5;3483:7;3498:10;3516:18;3542:13;3563:18;3585:1;3563:23;:42;;3604:1;3563:42;;;3589:12;;;;3563:42;3613:31;;;;1747:5:6;1754:7;2046:5:1;:13;1747:5:6;2046::1;:13;:::i;:::-;-1:-1:-1;2069:7:1;:17;2079:7;2069;:17;:::i;:::-;;1980:113;;1773:12:6::1;1789:1;1773:17;1769:161;;1800:59;1812:10:::0;1839:19:::1;1845:13:::0;1839:2:::1;:19;:::i;:::-;1824:34;::::0;:12;:34:::1;:::i;:::-;1800:11;;;;;:59;;:::i;:::-;1894:27;1909:12:::0;-1:-1:-1;;1894:27:6::1;:::i;:::-;1878:44;::::0;-1:-1:-1;;1878:44:6::1;:::i;:::-;1867:7;:56:::0;1769:161:::1;1958:7;::::0;-1:-1:-1;;;;;1936:19:6;;::::1;;::::0;;;:7:::1;:19;::::0;;;;:29;;;;1971:7:::1;:18:::0;-1:-1:-1;;1995:28:6::1;;;::::0;-1:-1:-1;936:32:0;;-1:-1:-1;955:12:0;734:10:4;;655:96;955:12:0;936:18;:32::i;:::-;3836:17:5::1;:31;;;:164;;;;;3880:17;:29;;;:72;;;-1:-1:-1::0;3923:29:5;;3880:72:::1;:119;;;;3966:17;:33;;;3880:119;3835:231;;;;4013:17;:31;;;4012:32;:53;;;;-1:-1:-1::0;4048:12:5;;::::1;::::0;:17;::::1;4012:53;3824:296;;;4088:25;;-1:-1:-1::0;;;4088:25:5::1;;;;;;;;;;;3824:296;4130:17;:41;;;4126:151;;;4185:15:::0;;4198:1:::1;4185:20:::0;4181:90:::1;;4246:15:::0;;4224:38:::1;::::0;-1:-1:-1;;;4224:38:5;;::::1;::::0;::::1;10344:25:8::0;;;;10317:18;;4224:38:5::1;;;;;;;;4181:90;4302:2;4286:13;:18;;;4282:76;;;4321:30;::::0;-1:-1:-1;;;4321:30:5;;10552:4:8;10540:17;;4321:30:5::1;::::0;::::1;10522:36:8::0;10495:18;;4321:30:5::1;10380:184:8::0;4282:76:5::1;4375:17;:33;;;:112;;;;-1:-1:-1::0;4420:29:5;;4419:30:::1;::::0;:67:::1;;-1:-1:-1::0;4470:15:5::1;::::0;::::1;::::0;3342:12:1;;4454:31:5::1;4419:67;4364:176;;;4509:24;;-1:-1:-1::0;;;4509:24:5::1;;;;;;;;;;;4364:176;4546:56;4560:17:::0;4579:9;4590:11;4546:13:::1;:56::i;:::-;4609:37;4635:10;4609:25;;;;;:37;;:::i;:::-;4653:10;:24:::0;;-1:-1:-1;;;;;;4653:24:5::1;-1:-1:-1::0;;;;;4653:24:5;::::1;;::::0;;4693:12;;4684:6:::1;:21:::0;4693:12:::1;4726::::0;::::1;::::0;4711::::1;:27:::0;4744:34:::1;::::0;;;4818:15;;4784:49:::1;::::0;4839:18:::1;:35;4860:14:::0;4839:18;:35:::1;:::i;:::-;-1:-1:-1::0;;;;;;4880:30:5;::::1;;::::0;;;4916:25:::1;::::0;::::1;;::::0;;;4947:31;;:11:::1;:31:::0;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;;::::1;::::0;-1:-1:-1;;4947:31:5;;;;::::1;;-1:-1:-1::0;;4947:31:5;;;;;;::::1;;::::0;;::::1;::::0;;;::::1;-1:-1:-1::0;;4947:31:5;;;::::1;;::::0;;;::::1;-1:-1:-1::0;;4947:31:5;;;;::::1;;::::0;;;::::1;;-1:-1:-1::0;;;;4947:31:5;;;::::1;;::::0;;;::::1;-1:-1:-1::0;;;;4947:31:5;;;;;;;::::1;;::::0;;;::::1;::::0;;;::::1;-1:-1:-1::0;;;;4947:31:5;;;::::1;;::::0;;;::::1;-1:-1:-1::0;;;;4947:31:5;;;;;;;::::1;;::::0;;;::::1;;::::0;;4984:11:::1;:28;4998:14:::0;4984:11;:28:::1;:::i;:::-;-1:-1:-1::0;5045:15:5;;5018:24:::1;:42:::0;5045:15:::1;5083::::0;::::1;::::0;5066:14:::1;:32:::0;5123:10:::1;-1:-1:-1::0;;;;;5109:24:5;::::1;;5105:74;;5143:29;5161:10:::0;5143:17:::1;:29::i;:::-;3119:2064:::0;;;;;;;;;;395:14391;;8520:535:1;-1:-1:-1;;;;;8603:21:1;;8595:65;;;;-1:-1:-1;;;8595:65:1;;10771:2:8;8595:65:1;;;10753:21:8;10810:2;10790:18;;;10783:30;10849:33;10829:18;;;10822:61;10900:18;;8595:65:1;10569:355:8;8595:65:1;8747:6;8731:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;8899:18:1;;:9;:18;;;;;;;;;;;:28;;;;;;8952:37;10344:25:8;;;8952:37:1;;10317:18:8;8952:37:1;;;;;;;8520:535;;:::o;2426:187:0:-;2518:6;;;-1:-1:-1;;;;;2534:17:0;;;-1:-1:-1;;;;;;2534:17:0;;;;;;;2566:40;;2518:6;;;2534:17;2518:6;;2566:40;;2499:16;;2566:40;2489:124;2426:187;:::o;5187:549:5:-;5338:16;5368:17;:28;;;5364:120;;;5406:38;5432:11;5406:25;;;;;:38;;:::i;:::-;5465:12;;5453:24;;;;:::i;:::-;;;5364:120;5493:17;:33;;;5489:78;;;5548:12;;;;5536:24;;;;:::i;:::-;;;5489:78;5576:17;:31;;;5572:76;;;5629:12;;;;5617:24;;;;:::i;:::-;;;5572:76;558:5;5657:8;:26;5653:79;;;5700:25;;-1:-1:-1;;;5700:25:5;;;;;10344::8;;;10317:18;;5700:25:5;10198:177:8;5653:79:5;5332:404;5187:549;;;:::o;1674:396:7:-;1820:4;1816:2;1812:13;1802:258;;1975:10;1969:4;1962:24;2047:4;2041;2034:18;1802:258;1674:396;:::o;13768:115:5:-;1094:13:0;:11;:13::i;:::-;13845:33:5::1;13869:8;13845:23;;;;;:33;;:::i;12073:91:1:-:0;;;;:::o;1359:130:0:-;1273:6;;-1:-1:-1;;;;;1273:6:0;734:10:4;1422:23:0;1414:68;;;;-1:-1:-1;;;1414:68:0;;11261:2:8;1414:68:0;;;11243:21:8;;;11280:18;;;11273:30;11339:34;11319:18;;;11312:62;11391:18;;1414:68:0;11059:356:8;1414:68:0;1359:130::o;2074:198::-;1094:13;:11;:13::i;:::-;-1:-1:-1;;;;;2162:22:0;::::1;2154:73;;;::::0;-1:-1:-1;;;2154:73:0;;11622:2:8;2154:73:0::1;::::0;::::1;11604:21:8::0;11661:2;11641:18;;;11634:30;11700:34;11680:18;;;11673:62;-1:-1:-1;;;11751:18:8;;;11744:36;11797:19;;2154:73:0::1;11420:402:8::0;2154:73:0::1;2237:28;2256:8:::0;2237:18:::1;:28::i;14:127:8:-:0;75:10;70:3;66:20;63:1;56:31;106:4;103:1;96:15;130:4;127:1;120:15;146:275;217:2;211:9;282:2;263:13;;-1:-1:-1;;259:27:8;247:40;;-1:-1:-1;;;;;302:34:8;;338:22;;;299:62;296:88;;;364:18;;:::i;:::-;400:2;393:22;146:275;;-1:-1:-1;146:275:8:o;426:650::-;480:5;533:3;526:4;518:6;514:17;510:27;500:55;;551:1;548;541:12;500:55;574:13;;-1:-1:-1;;;;;599:26:8;;596:52;;;628:18;;:::i;:::-;667:4;695:53;738:2;719:13;;-1:-1:-1;;715:27:8;711:36;;695:53;:::i;:::-;773:2;764:7;757:19;817:3;812:2;807;799:6;795:15;791:24;788:33;785:53;;;834:1;831;824:12;785:53;856:1;866:134;880:2;877:1;874:9;866:134;;;969:14;;;965:23;;959:30;937:15;;;933:24;;926:64;891:10;;866:134;;;-1:-1:-1;1043:1:8;1020:16;;;1016:25;;;1009:36;;;;1024:7;426:650;-1:-1:-1;;;426:650:8:o;1081:160::-;1158:13;;1211:4;1200:16;;1190:27;;1180:55;;1231:1;1228;1221:12;1180:55;1081:160;;;:::o;1246:177::-;1325:13;;-1:-1:-1;;;;;1367:31:8;;1357:42;;1347:70;;1413:1;1410;1403:12;1428:164;1504:13;;1553;;1546:21;1536:32;;1526:60;;1582:1;1579;1572:12;1597:1029;1671:5;1701:6;1744:2;1732:9;1727:3;1723:19;1719:28;1716:48;;;1760:1;1757;1750:12;1716:48;1793:2;1787:9;1823:15;;;;-1:-1:-1;;;;;1853:34:8;;1889:22;;;1850:62;1847:88;;;1915:18;;:::i;:::-;1955:10;1951:2;1944:22;1984:6;1975:15;;2014:37;2041:9;2014:37;:::i;:::-;2006:6;1999:53;2085:46;2127:2;2116:9;2112:18;2085:46;:::i;:::-;2080:2;2072:6;2068:15;2061:71;2165:46;2207:2;2196:9;2192:18;2165:46;:::i;:::-;2160:2;2152:6;2148:15;2141:71;2245:46;2287:2;2276:9;2272:18;2245:46;:::i;:::-;2240:2;2232:6;2228:15;2221:71;2326:47;2368:3;2357:9;2353:19;2326:47;:::i;:::-;2320:3;2312:6;2308:16;2301:73;2408:47;2450:3;2439:9;2435:19;2408:47;:::i;:::-;2402:3;2394:6;2390:16;2383:73;2490:47;2532:3;2521:9;2517:19;2490:47;:::i;:::-;2484:3;2476:6;2472:16;2465:73;2572:47;2614:3;2603:9;2599:19;2572:47;:::i;:::-;2566:3;2558:6;2554:16;2547:73;;;1597:1029;;;;:::o;2631:661::-;2703:5;2756:3;2749:4;2741:6;2737:17;2733:27;2723:55;;2774:1;2771;2764:12;2723:55;2807:2;2801:9;2849:2;2837:15;;-1:-1:-1;;;;;2867:34:8;;2903:22;;;2864:62;2861:88;;;2929:18;;:::i;:::-;2965:2;2958:22;3000:6;3041:2;3029:15;;3056;;;3053:35;;;3084:1;3081;3074:12;3053:35;3108:6;3123:139;3139:6;3134:3;3131:15;3123:139;;;3207:10;;3195:23;;3247:4;3238:14;;;;3156;3123:139;;;-1:-1:-1;3280:6:8;;2631:661;-1:-1:-1;;;;;2631:661:8:o;3297:650::-;3358:5;3411:3;3404:4;3396:6;3392:17;3388:27;3378:55;;3429:1;3426;3419:12;3378:55;3462:2;3456:9;;;3492:15;;-1:-1:-1;;;;;3522:34:8;;3558:22;;;3519:62;3516:88;;;3584:18;;:::i;:::-;3624:10;3620:2;3613:22;;3655:6;3696:2;3688:6;3684:15;3722:3;3714:6;3711:15;3708:35;;;3739:1;3736;3729:12;3952:1485;4210:6;4218;4226;4234;4242;4250;4258;4266;4274;4282;4335:3;4323:9;4314:7;4310:23;4306:33;4303:53;;;4352:1;4349;4342:12;4303:53;4379:16;;-1:-1:-1;;;;;4444:14:8;;;4441:34;;;4471:1;4468;4461:12;4441:34;4494:61;4547:7;4538:6;4527:9;4523:22;4494:61;:::i;:::-;4484:71;;4601:2;4590:9;4586:18;4580:25;4564:41;;4630:2;4620:8;4617:16;4614:36;;;4646:1;4643;4636:12;4614:36;4669:63;4724:7;4713:8;4702:9;4698:24;4669:63;:::i;:::-;4659:73;;4772:2;4761:9;4757:18;4751:25;4741:35;;4795:47;4838:2;4827:9;4823:18;4795:47;:::i;:::-;4785:57;;4861:50;4906:3;4895:9;4891:19;4861:50;:::i;:::-;4851:60;;4930:75;4997:7;4991:3;4980:9;4976:19;4930:75;:::i;:::-;4920:85;;5051:3;5040:9;5036:19;5030:26;5014:42;;5081:2;5071:8;5068:16;5065:36;;;5097:1;5094;5087:12;5065:36;;5120:63;5175:7;5164:8;5153:9;5149:24;5120:63;:::i;:::-;5110:73;;;5202:50;5247:3;5236:9;5232:19;5202:50;:::i;:::-;5192:60;;5271:76;5339:7;5333:3;5322:9;5318:19;5271:76;:::i;:::-;5261:86;;5366:65;5423:7;5417:3;5406:9;5402:19;5366:65;:::i;:::-;5356:75;;3952:1485;;;;;;;;;;;;;:::o;5574:380::-;5653:1;5649:12;;;;5696;;;5717:61;;5771:4;5763:6;5759:17;5749:27;;5717:61;5824:2;5816:6;5813:14;5793:18;5790:38;5787:161;;5870:10;5865:3;5861:20;5858:1;5851:31;5905:4;5902:1;5895:15;5933:4;5930:1;5923:15;5787:161;;5574:380;;;:::o;6085:545::-;6187:2;6182:3;6179:11;6176:448;;;6223:1;6248:5;6244:2;6237:17;6293:4;6289:2;6279:19;6363:2;6351:10;6347:19;6344:1;6340:27;6334:4;6330:38;6399:4;6387:10;6384:20;6381:47;;;-1:-1:-1;6422:4:8;6381:47;6477:2;6472:3;6468:12;6465:1;6461:20;6455:4;6451:31;6441:41;;6532:82;6550:2;6543:5;6540:13;6532:82;;;6595:17;;;6576:1;6565:13;6532:82;;;6536:3;;;6085:545;;;:::o;6806:1352::-;6926:10;;-1:-1:-1;;;;;6948:30:8;;6945:56;;;6981:18;;:::i;:::-;7010:97;7100:6;7060:38;7092:4;7086:11;7060:38;:::i;:::-;7054:4;7010:97;:::i;:::-;7162:4;;7226:2;7215:14;;7243:1;7238:663;;;;7945:1;7962:6;7959:89;;;-1:-1:-1;8014:19:8;;;8008:26;7959:89;-1:-1:-1;;6763:1:8;6759:11;;;6755:24;6751:29;6741:40;6787:1;6783:11;;;6738:57;8061:81;;7208:944;;7238:663;6032:1;6025:14;;;6069:4;6056:18;;-1:-1:-1;;7274:20:8;;;7392:236;7406:7;7403:1;7400:14;7392:236;;;7495:19;;;7489:26;7474:42;;7587:27;;;;7555:1;7543:14;;;;7422:19;;7392:236;;;7396:3;7656:6;7647:7;7644:19;7641:201;;;7717:19;;;7711:26;-1:-1:-1;;7800:1:8;7796:14;;;7812:3;7792:24;7788:37;7784:42;7769:58;7754:74;;7641:201;-1:-1:-1;;;;;7888:1:8;7872:14;;;7868:22;7855:36;;-1:-1:-1;6806:1352:8:o;8163:127::-;8224:10;8219:3;8215:20;8212:1;8205:31;8255:4;8252:1;8245:15;8279:4;8276:1;8269:15;8295:422;8384:1;8427:5;8384:1;8441:270;8462:7;8452:8;8449:21;8441:270;;;8521:4;8517:1;8513:6;8509:17;8503:4;8500:27;8497:53;;;8530:18;;:::i;:::-;8580:7;8570:8;8566:22;8563:55;;;8600:16;;;;8563:55;8679:22;;;;8639:15;;;;8441:270;;;8445:3;8295:422;;;;;:::o;8722:806::-;8771:5;8801:8;8791:80;;-1:-1:-1;8842:1:8;8856:5;;8791:80;8890:4;8880:76;;-1:-1:-1;8927:1:8;8941:5;;8880:76;8972:4;8990:1;8985:59;;;;9058:1;9053:130;;;;8965:218;;8985:59;9015:1;9006:10;;9029:5;;;9053:130;9090:3;9080:8;9077:17;9074:43;;;9097:18;;:::i;:::-;-1:-1:-1;;9153:1:8;9139:16;;9168:5;;8965:218;;9267:2;9257:8;9254:16;9248:3;9242:4;9239:13;9235:36;9229:2;9219:8;9216:16;9211:2;9205:4;9202:12;9198:35;9195:77;9192:159;;;-1:-1:-1;9304:19:8;;;9336:5;;9192:159;9383:34;9408:8;9402:4;9383:34;:::i;:::-;9453:6;9449:1;9445:6;9441:19;9432:7;9429:32;9426:58;;;9464:18;;:::i;:::-;9502:20;;-1:-1:-1;8722:806:8;;;;;:::o;9533:140::-;9591:5;9620:47;9661:4;9651:8;9647:19;9641:4;9620:47;:::i;:::-;9611:56;9533:140;-1:-1:-1;;;9533:140:8:o;9678:168::-;9751:9;;;9782;;9799:15;;;9793:22;;9779:37;9769:71;;9820:18;;:::i;9851:209::-;9883:1;9909;9899:132;;9953:10;9948:3;9944:20;9941:1;9934:31;9988:4;9985:1;9978:15;10016:4;10013:1;10006:15;9899:132;-1:-1:-1;10045:9:8;;9851:209::o;10065:128::-;10132:9;;;10153:11;;;10150:37;;;10167:18;;:::i;10929:125::-;10994:9;;;11015:10;;;11012:36;;;11028:18;;:::i;11420:402::-;395:14391:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","linkReferences":{},"cborAuxdata":{"1":{"value":"0xa2646970667358221220f0883b06564851f25c2214f07da7f7c972f341f687d3de12c8903d945027bfe064736f6c63430008110033","offset":11681}},"transformations":[{"type":"insert","offset":11734,"reason":"constructorArguments"}],"transformationValues":{"constructorArguments":"0x000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000000000000000000000000000000000003f00de810000000000000000000000000000000000000000000000000000000000000012000000000000000000000000157ae92276501b73b1a17d226bb89875d6eaafd1000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000157ae92276501b73b1a17d226bb89875d6eaafd10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000194e494c414d205265736f75726365732d204d696e64576176650000000000000000000000000000000000000000000000000000000000000000000000000000044e494c41000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}},"runtimeBytecode":{"onchainBytecode":"0x608060405234801561001057600080fd5b50600436106102e95760003560e01c8063883356d911610191578063af465a27116100e3578063de0060ca11610097578063f820f56711610071578063f820f56714610625578063f91f825d14610636578063ffa1ad741461064957600080fd5b8063de0060ca146105ec578063f19c4e3b146105ff578063f2fde38b1461061257600080fd5b8063d48e4127116100c8578063d48e412714610597578063d8f67851146105a0578063dd62ed3e146105b357600080fd5b8063af465a271461057c578063b7bda68f1461058457600080fd5b80639703a19d11610145578063a476df611161011f578063a476df611461054e578063a9059cbb14610561578063a9d866851461057457600080fd5b80639703a19d1461050b578063a32f697614610514578063a457c2d71461053b57600080fd5b80638dac7191116101765780638dac7191146104c75780638e8c10a2146104ee57806395d89b411461050357600080fd5b8063883356d9146104925780638da5cb5b146104a257600080fd5b8063313ce5671161024a57806346b45af7116101fe5780635a3990ce116101d85780635a3990ce1461046557806370a0823114610477578063715018a61461048a57600080fd5b806346b45af71461043d5780634ac0bc3214610448578063542e96671461045c57600080fd5b8063395093511161022f578063395093511461040457806340c10f191461041757806342966c681461042a57600080fd5b8063313ce567146103ac578063378dc3dc146103dd57600080fd5b806323b872dd116102a15780632d838119116102865780632d8381191461037a5780632e0ee48e1461038d5780632fa782eb146103a357600080fd5b806323b872dd1461035e5780632ab4d0521461037157600080fd5b806306fdde03116102d257806306fdde0314610321578063095ea7b31461032957806318160ddd1461034c57600080fd5b806302252c4d146102ee578063044ab74e14610303575b600080fd5b6103016102fc366004611c4d565b610685565b005b61030b610747565b6040516103189190611c66565b60405180910390f35b61030b6107d5565b61033c610337366004611ccb565b610867565b6040519015158152602001610318565b6002545b604051908152602001610318565b61033c61036c366004611cf5565b610881565b610350600e5481565b610350610388366004611c4d565b610953565b600f54670100000000000000900460ff1661033c565b61035060115481565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000012168152602001610318565b6103507f000000000000000000000000000000000000000000000000000000003f00de8181565b61033c610412366004611ccb565b6109ae565b610301610425366004611ccb565b6109ed565b610301610438366004611c4d565b610adb565b600f5460ff1661033c565b600f5465010000000000900460ff1661033c565b61035060125481565b600f546301000000900460ff1661033c565b610350610485366004611d31565b610b18565b610301610b85565b600f54610100900460ff1661033c565b600a546001600160a01b03165b6040516001600160a01b039091168152602001610318565b6104af7f000000000000000000000000157ae92276501b73b1a17d226bb89875d6eaafd181565b600f546601000000000000900460ff1661033c565b61030b610b97565b61035060095481565b6103507f000000000000000000000000000000000000000000000000000000000000000081565b61033c610549366004611ccb565b610ba6565b61030161055c366004611d62565b610c5b565b61033c61056f366004611ccb565b610ce1565b61030b610dac565b610350610db9565b6010546104af906001600160a01b031681565b610350600d5481565b6103016105ae366004611c4d565b610dc9565b6103506105c1366004611e13565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b600f54640100000000900460ff1661033c565b61030161060d366004611ccb565b610e90565b610301610620366004611d31565b610f8c565b600f5462010000900460ff1661033c565b610301610644366004611c4d565b610f9d565b61030b6040518060400160405280600881526020017f646566695f765f3300000000000000000000000000000000000000000000000081525081565b61068d61116c565b600f546301000000900460ff166106d0576040517f6273340f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d54811161070b576040517fa43d2d7600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d8190556040518181527f2905481c6fd1a037492016c4760435a52203d82a6f34dc3de40f464c1bf42d59906020015b60405180910390a150565b600c805461075490611e46565b80601f016020809104026020016040519081016040528092919081815260200182805461078090611e46565b80156107cd5780601f106107a2576101008083540402835291602001916107cd565b820191906000526020600020905b8154815290600101906020018083116107b057829003601f168201915b505050505081565b6060600380546107e490611e46565b80601f016020809104026020016040519081016040528092919081815260200182805461081090611e46565b801561085d5780601f106108325761010080835404028352916020019161085d565b820191906000526020600020905b81548152906001019060200180831161084057829003601f168201915b5050505050905090565b6000336108758185856111c6565b60019150505b92915050565b60008061088e858461131e565b9050600061089b84611361565b90506000816108aa8487611e96565b6108b49190611e96565b600f549091506301000000900460ff161561090f57600d54816108d688610b18565b6108e09190611ea9565b111561090f5760405163f6202a8f60e01b81526001600160a01b03871660048201526024015b60405180910390fd5b821561092d5760105461092d9088906001600160a01b031685611388565b811561093d5761093d878361143a565b610948878783611483565b979650505050505050565b6000600754821115610991576040517fc91fa8bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061099b61149c565b90506109a78184611ebc565b9392505050565b3360008181526001602090815260408083206001600160a01b038716845290915281205490919061087590829086906109e8908790611ea9565b6111c6565b6109f561116c565b600f5460ff16610a1857604051630732158d60e31b815260040160405180910390fd5b600f546301000000900460ff1615610a6b57600d5481610a3784610b18565b610a419190611ea9565b1115610a6b5760405163f6202a8f60e01b81526001600160a01b0383166004820152602401610906565b600f54640100000000900460ff1615610acd57600e5481610a8b60025490565b610a959190611ea9565b1115610acd576040517f44ea8ea500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ad782826114bf565b5050565b610ae361116c565b600f54610100900460ff16610b0b57604051636cb5913960e01b815260040160405180910390fd5b610b15338261143a565b50565b60007f000000000000000000000000000000000000000000000000000000000000000015610b62576001600160a01b03821660009081526005602052604090205461087b90610953565b6001600160a01b03821660009081526020819052604090205461087b565b919050565b610b8d61116c565b610b95611508565b565b6060600480546107e490611e46565b3360008181526001602090815260408083206001600160a01b038716845290915281205490919083811015610c435760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610906565b610c5082868684036111c6565b506001949350505050565b610c6361116c565b600f5462010000900460ff16610ca5576040517f70a43fce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c610cb18282611f2c565b507f4456a0b562609d67398ddb488f136db285cd3c92343e0a7ba684925669237ade8160405161073c9190611c66565b600080610cee338461131e565b90506000610cfb84611361565b9050600081610d0a8487611e96565b610d149190611e96565b600f549091506301000000900460ff1615610d6a57600d5481610d3688610b18565b610d409190611ea9565b1115610d6a5760405163f6202a8f60e01b81526001600160a01b0387166004820152602401610906565b8215610d8857601054610d889033906001600160a01b031685611388565b8115610d9857610d98338361143a565b610da2868261151a565b9695505050505050565b600b805461075490611e46565b6000610dc460025490565b905090565b610dd161116c565b600f546601000000000000900460ff16610e17576040517fcd9e529800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081600954601254610e2a9190611ea9565b610e349190611ea9565b90506107d0811115610e5c57604051633e474e0d60e01b815260048101829052602401610906565b601282905560405182907fc1ff65ee907dc079b64ed9913d53f4bd593bd6ebd9b2a2708db2916d49e17ec390600090a25050565b610e9861116c565b600f5465010000000000900460ff16610edd576040517fc8a478a500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081600954601254610ef09190611ea9565b610efa9190611ea9565b90506107d0811115610f2257604051633e474e0d60e01b815260048101829052602401610906565b610f2b836110c9565b6010805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03851690811790915560118390556040518391907facc44e32fd5ca4240f6dbe6e8cf4eb49349c17c5ce5f80f1919a9c97b50d398a90600090a3505050565b610f9461116c565b610b15816110df565b610fa561116c565b600f54670100000000000000900460ff16610fd357604051630800e34b60e41b815260040160405180910390fd5b610fdc81611528565b60405181907f76e1296412dac7b50002658bf9aab02d0cfe366f373222d5c14d0168ee8199e390600090a250565b6001600160a01b0382166110605760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610906565b80600260008282546110729190611ea9565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b8060601b610b155763d92e233d6000526004601cfd5b6110e761116c565b6001600160a01b0381166111635760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610906565b610b158161156b565b600a546001600160a01b03163314610b955760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610906565b6001600160a01b0383166112415760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b0382166112bd5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b600060115460001415801561134157506010546001600160a01b03848116911614155b1561087b57612710601154836113579190611fec565b6109a79190611ebc565b6000601254600014610b80576127106012548361137e9190611fec565b61087b9190611ebc565b7f00000000000000000000000000000000000000000000000000000000000000001561142f57801561142a5760006113be61149c565b905060006113cc8284611fec565b90506113da858583846115ca565b836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161141f91815260200190565b60405180910390a350505b505050565b61142a8383836116ad565b7f00000000000000000000000000000000000000000000000000000000000000001561147957604051636cb5913960e01b815260040160405180910390fd5b610ad7828261189c565b600033611491858285611a05565b610c50858585611a91565b60008060006114a9611b0e565b90925090506114b88183611ebc565b9250505090565b7f0000000000000000000000000000000000000000000000000000000000000000156114fe57604051630732158d60e31b815260040160405180910390fd5b610ad7828261100a565b61151061116c565b610b95600061156b565b600033610875818585611a91565b7f000000000000000000000000000000000000000000000000000000000000000061156657604051630800e34b60e41b815260040160405180910390fd5b600955565b600a80546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b03841660009081526005602052604090205482811015611636576040517fe450d38c0000000000000000000000000000000000000000000000000000000081526001600160a01b03851660048201526024810182905260448101849052606401610906565b6001600160a01b03851660009081526005602052604090205461165a908490611e96565b6001600160a01b03808716600090815260056020526040808220939093559086168152205461168a908390611ea9565b6001600160a01b0390941660009081526005602052604090209390935550505050565b6001600160a01b0383166117295760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b0382166117a55760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b038316600090815260208190526040902054818110156118345760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35b50505050565b6001600160a01b0382166119185760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b038216600090815260208190526040902054818110156119a75760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146118965781811015611a845760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610906565b61189684848484036111c6565b7f00000000000000000000000000000000000000000000000000000000000000001561142f57611ac0836110c9565b611ac9826110c9565b80600003611b03576040517f76c4f5b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61142a838383611b24565b600080600754611b1c610db9565b915091509091565b6000611b2f82611bcb565b90506000611b3d8284611e96565b90506000806000611b4f868686611bde565b92509250925085600014611bc157611b69888885846115ca565b611b738286611c27565b866001600160a01b0316886001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef88604051611bb891815260200190565b60405180910390a35b5050505050505050565b60006127106009548361137e9190611fec565b600080600080611bec61149c565b90506000611bfa8289611fec565b90506000611c088389611fec565b90506000611c168489611fec565b929a91995091975095505050505050565b81600754611c359190611e96565b600755600854611c46908290611ea9565b6008555050565b600060208284031215611c5f57600080fd5b5035919050565b600060208083528351808285015260005b81811015611c9357858101830151858201604001528201611c77565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114610b8057600080fd5b60008060408385031215611cde57600080fd5b611ce783611cb4565b946020939093013593505050565b600080600060608486031215611d0a57600080fd5b611d1384611cb4565b9250611d2160208501611cb4565b9150604084013590509250925092565b600060208284031215611d4357600080fd5b6109a782611cb4565b634e487b7160e01b600052604160045260246000fd5b600060208284031215611d7457600080fd5b813567ffffffffffffffff80821115611d8c57600080fd5b818401915084601f830112611da057600080fd5b813581811115611db257611db2611d4c565b604051601f8201601f19908116603f01168101908382118183101715611dda57611dda611d4c565b81604052828152876020848701011115611df357600080fd5b826020860160208301376000928101602001929092525095945050505050565b60008060408385031215611e2657600080fd5b611e2f83611cb4565b9150611e3d60208401611cb4565b90509250929050565b600181811c90821680611e5a57607f821691505b602082108103611e7a57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561087b5761087b611e80565b8082018082111561087b5761087b611e80565b600082611ed957634e487b7160e01b600052601260045260246000fd5b500490565b601f82111561142a57600081815260208120601f850160051c81016020861015611f055750805b601f850160051c820191505b81811015611f2457828155600101611f11565b505050505050565b815167ffffffffffffffff811115611f4657611f46611d4c565b611f5a81611f548454611e46565b84611ede565b602080601f831160018114611f8f5760008415611f775750858301515b600019600386901b1c1916600185901b178555611f24565b600085815260208120601f198616915b82811015611fbe57888601518255948401946001909101908401611f9f565b5085821015611fdc5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b808202811582820484141761087b5761087b611e8056fea2646970667358221220f0883b06564851f25c2214f07da7f7c972f341f687d3de12c8903d945027bfe064736f6c63430008110033","recompiledBytecode":"0x608060405234801561001057600080fd5b50600436106102e95760003560e01c8063883356d911610191578063af465a27116100e3578063de0060ca11610097578063f820f56711610071578063f820f56714610625578063f91f825d14610636578063ffa1ad741461064957600080fd5b8063de0060ca146105ec578063f19c4e3b146105ff578063f2fde38b1461061257600080fd5b8063d48e4127116100c8578063d48e412714610597578063d8f67851146105a0578063dd62ed3e146105b357600080fd5b8063af465a271461057c578063b7bda68f1461058457600080fd5b80639703a19d11610145578063a476df611161011f578063a476df611461054e578063a9059cbb14610561578063a9d866851461057457600080fd5b80639703a19d1461050b578063a32f697614610514578063a457c2d71461053b57600080fd5b80638dac7191116101765780638dac7191146104c75780638e8c10a2146104ee57806395d89b411461050357600080fd5b8063883356d9146104925780638da5cb5b146104a257600080fd5b8063313ce5671161024a57806346b45af7116101fe5780635a3990ce116101d85780635a3990ce1461046557806370a0823114610477578063715018a61461048a57600080fd5b806346b45af71461043d5780634ac0bc3214610448578063542e96671461045c57600080fd5b8063395093511161022f578063395093511461040457806340c10f191461041757806342966c681461042a57600080fd5b8063313ce567146103ac578063378dc3dc146103dd57600080fd5b806323b872dd116102a15780632d838119116102865780632d8381191461037a5780632e0ee48e1461038d5780632fa782eb146103a357600080fd5b806323b872dd1461035e5780632ab4d0521461037157600080fd5b806306fdde03116102d257806306fdde0314610321578063095ea7b31461032957806318160ddd1461034c57600080fd5b806302252c4d146102ee578063044ab74e14610303575b600080fd5b6103016102fc366004611c4d565b610685565b005b61030b610747565b6040516103189190611c66565b60405180910390f35b61030b6107d5565b61033c610337366004611ccb565b610867565b6040519015158152602001610318565b6002545b604051908152602001610318565b61033c61036c366004611cf5565b610881565b610350600e5481565b610350610388366004611c4d565b610953565b600f54670100000000000000900460ff1661033c565b61035060115481565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610318565b6103507f000000000000000000000000000000000000000000000000000000000000000081565b61033c610412366004611ccb565b6109ae565b610301610425366004611ccb565b6109ed565b610301610438366004611c4d565b610adb565b600f5460ff1661033c565b600f5465010000000000900460ff1661033c565b61035060125481565b600f546301000000900460ff1661033c565b610350610485366004611d31565b610b18565b610301610b85565b600f54610100900460ff1661033c565b600a546001600160a01b03165b6040516001600160a01b039091168152602001610318565b6104af7f000000000000000000000000000000000000000000000000000000000000000081565b600f546601000000000000900460ff1661033c565b61030b610b97565b61035060095481565b6103507f000000000000000000000000000000000000000000000000000000000000000081565b61033c610549366004611ccb565b610ba6565b61030161055c366004611d62565b610c5b565b61033c61056f366004611ccb565b610ce1565b61030b610dac565b610350610db9565b6010546104af906001600160a01b031681565b610350600d5481565b6103016105ae366004611c4d565b610dc9565b6103506105c1366004611e13565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b600f54640100000000900460ff1661033c565b61030161060d366004611ccb565b610e90565b610301610620366004611d31565b610f8c565b600f5462010000900460ff1661033c565b610301610644366004611c4d565b610f9d565b61030b6040518060400160405280600881526020017f646566695f765f3300000000000000000000000000000000000000000000000081525081565b61068d61116c565b600f546301000000900460ff166106d0576040517f6273340f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d54811161070b576040517fa43d2d7600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d8190556040518181527f2905481c6fd1a037492016c4760435a52203d82a6f34dc3de40f464c1bf42d59906020015b60405180910390a150565b600c805461075490611e46565b80601f016020809104026020016040519081016040528092919081815260200182805461078090611e46565b80156107cd5780601f106107a2576101008083540402835291602001916107cd565b820191906000526020600020905b8154815290600101906020018083116107b057829003601f168201915b505050505081565b6060600380546107e490611e46565b80601f016020809104026020016040519081016040528092919081815260200182805461081090611e46565b801561085d5780601f106108325761010080835404028352916020019161085d565b820191906000526020600020905b81548152906001019060200180831161084057829003601f168201915b5050505050905090565b6000336108758185856111c6565b60019150505b92915050565b60008061088e858461131e565b9050600061089b84611361565b90506000816108aa8487611e96565b6108b49190611e96565b600f549091506301000000900460ff161561090f57600d54816108d688610b18565b6108e09190611ea9565b111561090f5760405163f6202a8f60e01b81526001600160a01b03871660048201526024015b60405180910390fd5b821561092d5760105461092d9088906001600160a01b031685611388565b811561093d5761093d878361143a565b610948878783611483565b979650505050505050565b6000600754821115610991576040517fc91fa8bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061099b61149c565b90506109a78184611ebc565b9392505050565b3360008181526001602090815260408083206001600160a01b038716845290915281205490919061087590829086906109e8908790611ea9565b6111c6565b6109f561116c565b600f5460ff16610a1857604051630732158d60e31b815260040160405180910390fd5b600f546301000000900460ff1615610a6b57600d5481610a3784610b18565b610a419190611ea9565b1115610a6b5760405163f6202a8f60e01b81526001600160a01b0383166004820152602401610906565b600f54640100000000900460ff1615610acd57600e5481610a8b60025490565b610a959190611ea9565b1115610acd576040517f44ea8ea500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ad782826114bf565b5050565b610ae361116c565b600f54610100900460ff16610b0b57604051636cb5913960e01b815260040160405180910390fd5b610b15338261143a565b50565b60007f000000000000000000000000000000000000000000000000000000000000000015610b62576001600160a01b03821660009081526005602052604090205461087b90610953565b6001600160a01b03821660009081526020819052604090205461087b565b919050565b610b8d61116c565b610b95611508565b565b6060600480546107e490611e46565b3360008181526001602090815260408083206001600160a01b038716845290915281205490919083811015610c435760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610906565b610c5082868684036111c6565b506001949350505050565b610c6361116c565b600f5462010000900460ff16610ca5576040517f70a43fce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c610cb18282611f2c565b507f4456a0b562609d67398ddb488f136db285cd3c92343e0a7ba684925669237ade8160405161073c9190611c66565b600080610cee338461131e565b90506000610cfb84611361565b9050600081610d0a8487611e96565b610d149190611e96565b600f549091506301000000900460ff1615610d6a57600d5481610d3688610b18565b610d409190611ea9565b1115610d6a5760405163f6202a8f60e01b81526001600160a01b0387166004820152602401610906565b8215610d8857601054610d889033906001600160a01b031685611388565b8115610d9857610d98338361143a565b610da2868261151a565b9695505050505050565b600b805461075490611e46565b6000610dc460025490565b905090565b610dd161116c565b600f546601000000000000900460ff16610e17576040517fcd9e529800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081600954601254610e2a9190611ea9565b610e349190611ea9565b90506107d0811115610e5c57604051633e474e0d60e01b815260048101829052602401610906565b601282905560405182907fc1ff65ee907dc079b64ed9913d53f4bd593bd6ebd9b2a2708db2916d49e17ec390600090a25050565b610e9861116c565b600f5465010000000000900460ff16610edd576040517fc8a478a500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081600954601254610ef09190611ea9565b610efa9190611ea9565b90506107d0811115610f2257604051633e474e0d60e01b815260048101829052602401610906565b610f2b836110c9565b6010805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03851690811790915560118390556040518391907facc44e32fd5ca4240f6dbe6e8cf4eb49349c17c5ce5f80f1919a9c97b50d398a90600090a3505050565b610f9461116c565b610b15816110df565b610fa561116c565b600f54670100000000000000900460ff16610fd357604051630800e34b60e41b815260040160405180910390fd5b610fdc81611528565b60405181907f76e1296412dac7b50002658bf9aab02d0cfe366f373222d5c14d0168ee8199e390600090a250565b6001600160a01b0382166110605760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610906565b80600260008282546110729190611ea9565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b8060601b610b155763d92e233d6000526004601cfd5b6110e761116c565b6001600160a01b0381166111635760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610906565b610b158161156b565b600a546001600160a01b03163314610b955760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610906565b6001600160a01b0383166112415760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b0382166112bd5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b600060115460001415801561134157506010546001600160a01b03848116911614155b1561087b57612710601154836113579190611fec565b6109a79190611ebc565b6000601254600014610b80576127106012548361137e9190611fec565b61087b9190611ebc565b7f00000000000000000000000000000000000000000000000000000000000000001561142f57801561142a5760006113be61149c565b905060006113cc8284611fec565b90506113da858583846115ca565b836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161141f91815260200190565b60405180910390a350505b505050565b61142a8383836116ad565b7f00000000000000000000000000000000000000000000000000000000000000001561147957604051636cb5913960e01b815260040160405180910390fd5b610ad7828261189c565b600033611491858285611a05565b610c50858585611a91565b60008060006114a9611b0e565b90925090506114b88183611ebc565b9250505090565b7f0000000000000000000000000000000000000000000000000000000000000000156114fe57604051630732158d60e31b815260040160405180910390fd5b610ad7828261100a565b61151061116c565b610b95600061156b565b600033610875818585611a91565b7f000000000000000000000000000000000000000000000000000000000000000061156657604051630800e34b60e41b815260040160405180910390fd5b600955565b600a80546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b03841660009081526005602052604090205482811015611636576040517fe450d38c0000000000000000000000000000000000000000000000000000000081526001600160a01b03851660048201526024810182905260448101849052606401610906565b6001600160a01b03851660009081526005602052604090205461165a908490611e96565b6001600160a01b03808716600090815260056020526040808220939093559086168152205461168a908390611ea9565b6001600160a01b0390941660009081526005602052604090209390935550505050565b6001600160a01b0383166117295760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b0382166117a55760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b038316600090815260208190526040902054818110156118345760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35b50505050565b6001600160a01b0382166119185760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b038216600090815260208190526040902054818110156119a75760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146118965781811015611a845760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610906565b61189684848484036111c6565b7f00000000000000000000000000000000000000000000000000000000000000001561142f57611ac0836110c9565b611ac9826110c9565b80600003611b03576040517f76c4f5b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61142a838383611b24565b600080600754611b1c610db9565b915091509091565b6000611b2f82611bcb565b90506000611b3d8284611e96565b90506000806000611b4f868686611bde565b92509250925085600014611bc157611b69888885846115ca565b611b738286611c27565b866001600160a01b0316886001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef88604051611bb891815260200190565b60405180910390a35b5050505050505050565b60006127106009548361137e9190611fec565b600080600080611bec61149c565b90506000611bfa8289611fec565b90506000611c088389611fec565b90506000611c168489611fec565b929a91995091975095505050505050565b81600754611c359190611e96565b600755600854611c46908290611ea9565b6008555050565b600060208284031215611c5f57600080fd5b5035919050565b600060208083528351808285015260005b81811015611c9357858101830151858201604001528201611c77565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114610b8057600080fd5b60008060408385031215611cde57600080fd5b611ce783611cb4565b946020939093013593505050565b600080600060608486031215611d0a57600080fd5b611d1384611cb4565b9250611d2160208501611cb4565b9150604084013590509250925092565b600060208284031215611d4357600080fd5b6109a782611cb4565b634e487b7160e01b600052604160045260246000fd5b600060208284031215611d7457600080fd5b813567ffffffffffffffff80821115611d8c57600080fd5b818401915084601f830112611da057600080fd5b813581811115611db257611db2611d4c565b604051601f8201601f19908116603f01168101908382118183101715611dda57611dda611d4c565b81604052828152876020848701011115611df357600080fd5b826020860160208301376000928101602001929092525095945050505050565b60008060408385031215611e2657600080fd5b611e2f83611cb4565b9150611e3d60208401611cb4565b90509250929050565b600181811c90821680611e5a57607f821691505b602082108103611e7a57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561087b5761087b611e80565b8082018082111561087b5761087b611e80565b600082611ed957634e487b7160e01b600052601260045260246000fd5b500490565b601f82111561142a57600081815260208120601f850160051c81016020861015611f055750805b601f850160051c820191505b81811015611f2457828155600101611f11565b505050505050565b815167ffffffffffffffff811115611f4657611f46611d4c565b611f5a81611f548454611e46565b84611ede565b602080601f831160018114611f8f5760008415611f775750858301515b600019600386901b1c1916600185901b178555611f24565b600085815260208120601f198616915b82811015611fbe57888601518255948401946001909101908401611f9f565b5085821015611fdc5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b808202811582820484141761087b5761087b611e8056fea2646970667358221220f0883b06564851f25c2214f07da7f7c972f341f687d3de12c8903d945027bfe064736f6c63430008110033","sourceMap":"395:14391:5:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8278:392;;;;;;:::i;:::-;;:::i;:::-;;672:25;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2158:98:1;;;:::i;4444:197::-;;;;;;:::i;:::-;;:::i;:::-;;;1377:14:8;;1370:22;1352:41;;1340:2;1325:18;4444:197:1;1212:187:8;3255:106:1;3342:12;;3255:106;;;1550:25:8;;;1538:2;1523:18;3255:106:1;1404:177:8;11602:700:5;;;;;;:::i;:::-;;:::i;846:29::-;;;;;;5254:229:6;;;;;;:::i;:::-;;:::i;7622:94:5:-;7686:11;:25;;;;;;7622:94;;1328:21;;;;;;6972:92;;;2091:4:8;7050:9:5;2079:17:8;2061:36;;2049:2;2034:18;6972:92:5;1919:184:8;701:38:5;;;;;5854:234:1;;;;;;:::i;:::-;;:::i;12533:471:5:-;;;;;;:::i;:::-;;:::i;13188:150::-;;;;;;:::i;:::-;;:::i;5868:90::-;5930:11;:23;;;5868:90;;7174:88;7235:11;:22;;;;;;7174:88;;1353:27;;;;;;6296:114;6370:11;:35;;;;;;6296:114;;2199:214:6;;;;;;:::i;:::-;;:::i;13504:91:5:-;;;:::i;6054:90::-;6116:11;:23;;;;;;6054:90;;1201:85:0;1273:6;;-1:-1:-1;;;;;1273:6:0;1201:85;;;-1:-1:-1;;;;;2463:55:8;;;2445:74;;2433:2;2418:18;1201:85:0;2299:226:8;1216:42:5;;;;;7383:98;7449:11;:27;;;;;;7383:98;;2369:102:1;;;:::i;673:22:6:-;;;;;;743:56:5;;;;;6575:427:1;;;;;;:::i;:::-;;:::i;7860:232:5:-;;;;;;:::i;:::-;;:::i;10534:685::-;;;;;;:::i;:::-;;:::i;636:32::-;;;:::i;1104:88:6:-;;;:::i;1299:25:5:-;;;;;-1:-1:-1;;;;;1299:25:5;;;803:39;;;;;;9859:374;;;;;;:::i;:::-;;:::i;3987:149:1:-;;;;;;:::i;:::-;-1:-1:-1;;;;;4102:18:1;;;4076:7;4102:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;3987:149;6544:98:5;6610:11;:27;;;;;;6544:98;;9249:443;;;;;;:::i;:::-;;:::i;13768:115::-;;;;;;:::i;:::-;;:::i;6760:107::-;6832:11;:30;;;;;;6760:107;;8822:218;;;;;;:::i;:::-;;:::i;567:43::-;;;;;;;;;;;;;;;;;;;;;8278:392;1094:13:0;:11;:13::i;:::-;6370:11:5;:35;;;;;;8375:79:::1;;8421:26;;;;;;;;;;;;;;8375:79;8484:24;;8463:17;:45;8459:106;;8525:33;;;;;;;;;;;;;;8459:106;8571:24;:44:::0;;;8626:39:::1;::::0;1550:25:8;;;8626:39:5::1;::::0;1538:2:8;1523:18;8626:39:5::1;;;;;;;;8278:392:::0;:::o;672:25::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;2158:98:1:-;2212:13;2244:5;2237:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2158:98;:::o;4444:197::-;4527:4;734:10:4;4581:32:1;734:10:4;4597:7:1;4606:6;4581:8;:32::i;:::-;4630:4;4623:11;;;4444:197;;;;;:::o;11602:700:5:-;11715:4;11727:17;11747:24;11758:4;11764:6;11747:10;:24::i;:::-;11727:44;;11777:23;11803:24;11820:6;11803:16;:24::i;:::-;11777:50;-1:-1:-1;11833:24:5;11777:50;11860:18;11869:9;11860:6;:18;:::i;:::-;:36;;;;:::i;:::-;6370:11;:35;11833:63;;-1:-1:-1;6370:35:5;;;;;11903:167;;;11980:24;;11961:16;11945:13;11955:2;11945:9;:13::i;:::-;:32;;;;:::i;:::-;:59;11941:123;;;12023:32;;-1:-1:-1;;;12023:32:5;;-1:-1:-1;;;;;2463:55:8;;12023:32:5;;;2445:74:8;2418:18;;12023:32:5;;;;;;;;11941:123;12080:14;;12076:88;;12135:10;;12104:53;;12129:4;;-1:-1:-1;;;;;12135:10:5;12147:9;12104:24;:53::i;:::-;12173:20;;12169:69;;12203:28;12209:4;12215:15;12203:5;:28::i;:::-;12251:46;12270:4;12276:2;12280:16;12251:18;:46::i;:::-;12244:53;11602:700;-1:-1:-1;;;;;;;11602:700:5:o;5254:229:6:-;5321:7;5350;;5340;:17;5336:70;;;5374:25;;;;;;;;;;;;;;5336:70;5412:19;5434:10;:8;:10::i;:::-;5412:32;-1:-1:-1;5457:21:6;5412:32;5457:7;:21;:::i;:::-;5450:28;5254:229;-1:-1:-1;;;5254:229:6:o;5854:234:1:-;734:10:4;5942:4:1;4102:18;;;:11;:18;;;;;;;;-1:-1:-1;;;;;4102:27:1;;;;;;;;;;5942:4;;734:10:4;5996:64:1;;734:10:4;;4102:27:1;;6021:38;;6049:10;;6021:38;:::i;:::-;5996:8;:64::i;12533:471:5:-;1094:13:0;:11;:13::i;:::-;5930:11:5;:23;;;12600:60:::1;;12634:19;;-1:-1:-1::0;;;12634:19:5::1;;;;;;;;;;;12600:60;6370:11:::0;:35;;;;;;12665:157:::1;;;12732:24;;12723:6;12707:13;12717:2;12707:9;:13::i;:::-;:22;;;;:::i;:::-;:49;12703:113;;;12775:32;::::0;-1:-1:-1;;;12775:32:5;;-1:-1:-1;;;;;2463:55:8;;12775:32:5::1;::::0;::::1;2445:74:8::0;2418:18;;12775:32:5::1;2299:226:8::0;12703:113:5::1;6610:11:::0;:27;;;;;;12827:143:::1;;;12886:14;;12877:6;12861:13;3342:12:1::0;;;3255:106;12861:13:5::1;:22;;;;:::i;:::-;:39;12857:107;;;12919:36;;;;;;;;;;;;;;12857:107;12976:23;12988:2;12992:6;12976:11;:23::i;:::-;12533:471:::0;;:::o;13188:150::-;1094:13:0;:11;:13::i;:::-;6116:11:5;:23;;;;;;13243:60:::1;;13277:19;;-1:-1:-1::0;;;13277:19:5::1;;;;;;;;;;;13243:60;13308:25;13314:10;13326:6;13308:5;:25::i;:::-;13188:150:::0;:::o;2199:214:6:-;2265:7;2284:12;2280:129;;;-1:-1:-1;;;;;2333:16:6;;;;;;:7;:16;;;;;;2313:37;;:19;:37::i;2280:129::-;-1:-1:-1;;;;;3519:18:1;;3493:7;3519:18;;;;;;;;;;;2378:24:6;3419:125:1;2280:129:6;2199:214;;;:::o;13504:91:5:-;1094:13:0;:11;:13::i;:::-;13565:25:5::1;:23;:25::i;:::-;13504:91::o:0;2369:102:1:-;2425:13;2457:7;2450:14;;;;;:::i;6575:427::-;734:10:4;6668:4:1;4102:18;;;:11;:18;;;;;;;;-1:-1:-1;;;;;4102:27:1;;;;;;;;;;6668:4;;734:10:4;6812:15:1;6792:16;:35;;6784:85;;;;-1:-1:-1;;;6784:85:1;;5286:2:8;6784:85:1;;;5268:21:8;5325:2;5305:18;;;5298:30;5364:34;5344:18;;;5337:62;5435:7;5415:18;;;5408:35;5460:19;;6784:85:1;5084:401:8;6784:85:1;6903:60;6912:5;6919:7;6947:15;6928:16;:34;6903:8;:60::i;:::-;-1:-1:-1;6991:4:1;;6575:427;-1:-1:-1;;;;6575:427:1:o;7860:232:5:-;1094:13:0;:11;:13::i;:::-;6832:11:5;:30;;;;;;7939:74:::1;;7983:23;;;;;;;;;;;;;;7939:74;8018:11;:28;8032:14:::0;8018:11;:28:::1;:::i;:::-;;8057:30;8072:14;8057:30;;;;;;:::i;10534:685::-:0;10625:4;10637:17;10657:30;10668:10;10680:6;10657:10;:30::i;:::-;10637:50;;10693:23;10719:24;10736:6;10719:16;:24::i;:::-;10693:50;-1:-1:-1;10749:24:5;10693:50;10776:18;10785:9;10776:6;:18;:::i;:::-;:36;;;;:::i;:::-;6370:11;:35;10749:63;;-1:-1:-1;6370:35:5;;;;;10819:167;;;10896:24;;10877:16;10861:13;10871:2;10861:9;:13::i;:::-;:32;;;;:::i;:::-;:59;10857:123;;;10939:32;;-1:-1:-1;;;10939:32:5;;-1:-1:-1;;;;;2463:55:8;;10939:32:5;;;2445:74:8;2418:18;;10939:32:5;2299:226:8;10857:123:5;10996:14;;10992:94;;11057:10;;11020:59;;11045:10;;-1:-1:-1;;;;;11057:10:5;11069:9;11020:24;:59::i;:::-;11095:20;;11091:75;;11125:34;11131:10;11143:15;11125:5;:34::i;:::-;11178:36;11193:2;11197:16;11178:14;:36::i;:::-;11171:43;10534:685;-1:-1:-1;;;;;;10534:685:5:o;636:32::-;;;;;;;:::i;1104:88:6:-;1152:7;1174:13;3342:12:1;;;3255:106;1174:13:6;1167:20;;1104:88;:::o;9859:374:5:-;1094:13:0;:11;:13::i;:::-;7449:11:5;:27;;;;;;9935:69:::1;;9973:24;;;;;;;;;;;;;;9935:69;10009:16;10053:13;10043:7;;10028:12;;:22;;;;:::i;:::-;:38;;;;:::i;:::-;10009:57;;558:5;10076:8;:26;10072:79;;;10119:25;::::0;-1:-1:-1;;;10119:25:5;;::::1;::::0;::::1;1550::8::0;;;1523:18;;10119:25:5::1;1404:177:8::0;10072:79:5::1;10156:12;:28:::0;;;10195:33:::1;::::0;10171:13;;10195:33:::1;::::0;;;::::1;9929:304;9859:374:::0;:::o;9249:443::-;1094:13:0;:11;:13::i;:::-;7235:11:5;:22;;;;;;9346:59:::1;;9379:19;;;;;;;;;;;;;;9346:59;9411:16;9455:7;9445;;9430:12;;:22;;;;:::i;:::-;:32;;;;:::i;:::-;9411:51;;558:5;9472:8;:26;9468:79;;;9515:25;::::0;-1:-1:-1;;;9515:25:5;;::::1;::::0;::::1;1550::8::0;;;1523:18;;9515:25:5::1;1404:177:8::0;9468:79:5::1;9552:38;9578:11;9552:25;:38::i;:::-;9596:10;:24:::0;;-1:-1:-1;;9596:24:5::1;-1:-1:-1::0;;;;;9596:24:5;::::1;::::0;;::::1;::::0;;;9626:6:::1;:16:::0;;;9653:34:::1;::::0;9626:16;;9596:24;9653:34:::1;::::0;-1:-1:-1;;9653:34:5::1;9340:352;9249:443:::0;;:::o;13768:115::-;1094:13:0;:11;:13::i;:::-;13845:33:5::1;13869:8;13845:23;:33::i;8822:218::-:0;1094:13:0;:11;:13::i;:::-;7686:11:5;:25;;;;;;8893:65:::1;;8929:22;;-1:-1:-1::0;;;8929:22:5::1;;;;;;;;;;;8893:65;8963:32;8987:7;8963:23;:32::i;:::-;9007:28;::::0;9027:7;;9007:28:::1;::::0;;;::::1;8822:218:::0;:::o;8520:535:1:-;-1:-1:-1;;;;;8603:21:1;;8595:65;;;;-1:-1:-1;;;8595:65:1;;7896:2:8;8595:65:1;;;7878:21:8;7935:2;7915:18;;;7908:30;7974:33;7954:18;;;7947:61;8025:18;;8595:65:1;7694:355:8;8595:65:1;8747:6;8731:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;8899:18:1;;:9;:18;;;;;;;;;;;:28;;;;;;8952:37;1550:25:8;;;8952:37:1;;1523:18:8;8952:37:1;;;;;;;12533:471:5;;:::o;1674:396:7:-;1820:4;1816:2;1812:13;1802:258;;1975:10;1969:4;1962:24;2047:4;2041;2034:18;2074:198:0;1094:13;:11;:13::i;:::-;-1:-1:-1;;;;;2162:22:0;::::1;2154:73;;;::::0;-1:-1:-1;;;2154:73:0;;8256:2:8;2154:73:0::1;::::0;::::1;8238:21:8::0;8295:2;8275:18;;;8268:30;8334:34;8314:18;;;8307:62;8405:8;8385:18;;;8378:36;8431:19;;2154:73:0::1;8054:402:8::0;2154:73:0::1;2237:28;2256:8;2237:18;:28::i;1359:130::-:0;1273:6;;-1:-1:-1;;;;;1273:6:0;734:10:4;1422:23:0;1414:68;;;;-1:-1:-1;;;1414:68:0;;8663:2:8;1414:68:0;;;8645:21:8;;;8682:18;;;8675:30;8741:34;8721:18;;;8714:62;8793:18;;1414:68:0;8461:356:8;10457:340:1;-1:-1:-1;;;;;10558:19:1;;10550:68;;;;-1:-1:-1;;;10550:68:1;;9024:2:8;10550:68:1;;;9006:21:8;9063:2;9043:18;;;9036:30;9102:34;9082:18;;;9075:62;9173:6;9153:18;;;9146:34;9197:19;;10550:68:1;8822:400:8;10550:68:1;-1:-1:-1;;;;;10636:21:1;;10628:68;;;;-1:-1:-1;;;10628:68:1;;9429:2:8;10628:68:1;;;9411:21:8;9468:2;9448:18;;;9441:30;9507:34;9487:18;;;9480:62;9578:4;9558:18;;;9551:32;9600:19;;10628:68:1;9227:398:8;10628:68:1;-1:-1:-1;;;;;10707:18:1;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;10758:32;;1550:25:8;;;10758:32:1;;1523:18:8;10758:32:1;;;;;;;10457:340;;;:::o;14132:237:5:-;14219:17;14267:6;;14277:1;14267:11;;:35;;;;-1:-1:-1;14292:10:5;;-1:-1:-1;;;;;14282:20:5;;;14292:10;;14282:20;;14267:35;14263:102;;;505:6;14334;;14325;:15;;;;:::i;:::-;14324:34;;;;:::i;14555:229::-;14628:23;14688:12;;14704:1;14688:17;14684:96;;505:6;14743:12;;14734:6;:21;;;;:::i;:::-;14733:40;;;;:::i;6980:406:6:-;7092:12;7088:294;;;7118:12;;7114:207;;7142:19;7164:10;:8;:10::i;:::-;7142:32;-1:-1:-1;7184:15:6;7202:21;7142:32;7202:7;:21;:::i;:::-;7184:39;;7234:36;7243:4;7249:2;7253:7;7262;7234:8;:36::i;:::-;7300:2;-1:-1:-1;;;;;7285:27:6;7294:4;-1:-1:-1;;;;;7285:27:6;;7304:7;7285:27;;;;1550:25:8;;1538:2;1523:18;;1404:177;7285:27:6;;;;;;;;7132:189;;7114:207;6980:406;;;:::o;7088:294::-;7341:34;7357:4;7363:2;7367:7;7341:15;:34::i;4609:182::-;4684:12;4680:107;;;4713:19;;-1:-1:-1;;;4713:19:6;;;;;;;;;;;4680:107;4753:27;4765:7;4774:5;4753:11;:27::i;2590:257::-;2702:4;734:10:4;2756:37:6;2772:4;734:10:4;2787:5:6;2756:15;:37::i;:::-;2799:26;2809:4;2815:2;2819:5;2799:9;:26::i;8026:148::-;8068:7;8084:15;8101;8120:19;:17;:19::i;:::-;8083:56;;-1:-1:-1;8083:56:6;-1:-1:-1;8152:17:6;8083:56;;8152:17;:::i;:::-;8145:24;;;;8026:148;:::o;4164:182::-;4239:12;4235:107;;;4268:19;;-1:-1:-1;;;4268:19:6;;;;;;;;;;;4235:107;4308:27;4320:7;4329:5;4308:11;:27::i;1824:101:0:-;1094:13;:11;:13::i;:::-;1888:30:::1;1915:1;1888:18;:30::i;2993:191:6:-:0;3083:4;734:10:4;3135:27:6;734:10:4;3152:2:6;3156:5;3135:9;:27::i;4988:152::-;5053:12;5048:63;;5082:22;;-1:-1:-1;;;5082:22:6;;;;;;;;;;;5048:63;5117:7;:18;4988:152::o;2426:187:0:-;2518:6;;;-1:-1:-1;;;;;2534:17:0;;;-1:-1:-1;;2534:17:0;;;;;;;2566:40;;2518:6;;;2534:17;2518:6;;2566:40;;2499:16;;2566:40;2489:124;2426:187;:::o;8822:406:6:-;-1:-1:-1;;;;;8976:15:6;;8954:19;8976:15;;;:7;:15;;;;;;9001:24;;;8997:112;;;9042:60;;;;;-1:-1:-1;;;;;10023:55:8;;9042:60:6;;;10005:74:8;10095:18;;;10088:34;;;10138:18;;;10131:34;;;9978:18;;9042:60:6;9803:368:8;8997:112:6;-1:-1:-1;;;;;9132:15:6;;;;;;:7;:15;;;;;;:28;;9150:10;;9132:28;:::i;:::-;-1:-1:-1;;;;;9114:15:6;;;;;;;:7;:15;;;;;;:46;;;;9187:18;;;;;;;:36;;9208:15;;9187:36;:::i;:::-;-1:-1:-1;;;;;9166:18:6;;;;;;;:7;:18;;;;;:57;;;;-1:-1:-1;;;;8822:406:6:o;7456:788:1:-;-1:-1:-1;;;;;7552:18:1;;7544:68;;;;-1:-1:-1;;;7544:68:1;;10378:2:8;7544:68:1;;;10360:21:8;10417:2;10397:18;;;10390:30;10456:34;10436:18;;;10429:62;10527:7;10507:18;;;10500:35;10552:19;;7544:68:1;10176:401:8;7544:68:1;-1:-1:-1;;;;;7630:16:1;;7622:64;;;;-1:-1:-1;;;7622:64:1;;10784:2:8;7622:64:1;;;10766:21:8;10823:2;10803:18;;;10796:30;10862:34;10842:18;;;10835:62;10933:5;10913:18;;;10906:33;10956:19;;7622:64:1;10582:399:8;7622:64:1;-1:-1:-1;;;;;7768:15:1;;7746:19;7768:15;;;;;;;;;;;7801:21;;;;7793:72;;;;-1:-1:-1;;;7793:72:1;;11188:2:8;7793:72:1;;;11170:21:8;11227:2;11207:18;;;11200:30;11266:34;11246:18;;;11239:62;11337:8;11317:18;;;11310:36;11363:19;;7793:72:1;10986:402:8;7793:72:1;-1:-1:-1;;;;;7899:15:1;;;:9;:15;;;;;;;;;;;7917:20;;;7899:38;;8114:13;;;;;;;;;;:23;;;;;;8163:26;;1550:25:8;;;8114:13:1;;8163:26;;1523:18:8;8163:26:1;;;;;;;8200:37;7534:710;7456:788;;;:::o;9375:659::-;-1:-1:-1;;;;;9458:21:1;;9450:67;;;;-1:-1:-1;;;9450:67:1;;11595:2:8;9450:67:1;;;11577:21:8;11634:2;11614:18;;;11607:30;11673:34;11653:18;;;11646:62;11744:3;11724:18;;;11717:31;11765:19;;9450:67:1;11393:397:8;9450:67:1;-1:-1:-1;;;;;9613:18:1;;9588:22;9613:18;;;;;;;;;;;9649:24;;;;9641:71;;;;-1:-1:-1;;;9641:71:1;;11997:2:8;9641:71:1;;;11979:21:8;12036:2;12016:18;;;12009:30;12075:34;12055:18;;;12048:62;12146:4;12126:18;;;12119:32;12168:19;;9641:71:1;11795:398:8;9641:71:1;-1:-1:-1;;;;;9746:18:1;;:9;:18;;;;;;;;;;;9767:23;;;9746:44;;9883:12;:22;;;;;;;9931:37;1550:25:8;;;9746:9:1;;:18;9931:37;;1523:18:8;9931:37:1;;;;;;;6980:406:6;;;:::o;11078:411:1:-;-1:-1:-1;;;;;4102:18:1;;;11178:24;4102:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;-1:-1:-1;;11244:37:1;;11240:243;;11325:6;11305:16;:26;;11297:68;;;;-1:-1:-1;;;11297:68:1;;12400:2:8;11297:68:1;;;12382:21:8;12439:2;12419:18;;;12412:30;12478:31;12458:18;;;12451:59;12527:18;;11297:68:1;12198:353:8;11297:68:1;11407:51;11416:5;11423:7;11451:6;11432:16;:25;11407:8;:51::i;3382:374:6:-;3487:12;3483:269;;;3509:31;3535:4;3509:25;:31::i;:::-;3548:29;3574:2;3548:25;:29::i;:::-;3589:6;3599:1;3589:11;3585:62;;3619:19;;;;;;;;;;;;;;3585:62;3655:36;3674:4;3680:2;3684:6;3655:18;:36::i;8270:107::-;8321:7;8330;8353;;8362:9;:7;:9::i;:::-;8345:27;;;;8270:107;;:::o;5725:502::-;5835:12;5850:21;5863:7;5850:12;:21::i;:::-;5835:36;-1:-1:-1;5877:23:6;5903:14;5835:36;5903:7;:14;:::i;:::-;5877:40;;5924:15;5941:12;5955:23;5982:67;6001:7;6016:4;6028:15;5982:11;:67::i;:::-;5923:126;;;;;;6060:7;6071:1;6060:12;6056:167;;6082:53;6091:6;6099:9;6110:7;6119:15;6082:8;:53::i;:::-;6144:23;6156:4;6162;6144:11;:23::i;:::-;6197:9;-1:-1:-1;;;;;6180:36:6;6189:6;-1:-1:-1;;;;;6180:36:6;;6208:7;6180:36;;;;1550:25:8;;1538:2;1523:18;;1404:177;6180:36:6;;;;;;;;6056:167;5829:398;;;;;5725:502;;;:::o;6643:121::-;6704:7;448:6;6737:7;;6727;:17;;;;:::i;7551:376::-;7666:7;7675;7684;7699:19;7721:10;:8;:10::i;:::-;7699:32;-1:-1:-1;7737:15:6;7755:21;7699:32;7755:7;:21;:::i;:::-;7737:39;-1:-1:-1;7782:12:6;7797:18;7804:11;7797:4;:18;:::i;:::-;7782:33;-1:-1:-1;7821:23:6;7847:29;7865:11;7847:15;:29;:::i;:::-;7891:7;;7900:4;;-1:-1:-1;7891:7:6;;-1:-1:-1;7551:376:6;-1:-1:-1;;;;;;7551:376:6:o;6389:128::-;6472:4;6462:7;;:14;;;;:::i;:::-;6452:7;:24;6495:10;;:17;;6508:4;;6495:17;:::i;:::-;6482:10;:30;-1:-1:-1;;6389:128:6:o;14:180:8:-;73:6;126:2;114:9;105:7;101:23;97:32;94:52;;;142:1;139;132:12;94:52;-1:-1:-1;165:23:8;;14:180;-1:-1:-1;14:180:8:o;199:548::-;311:4;340:2;369;358:9;351:21;401:6;395:13;444:6;439:2;428:9;424:18;417:34;469:1;479:140;493:6;490:1;487:13;479:140;;;588:14;;;584:23;;578:30;554:17;;;573:2;550:26;543:66;508:10;;479:140;;;483:3;668:1;663:2;654:6;643:9;639:22;635:31;628:42;738:2;731;727:7;722:2;714:6;710:15;706:29;695:9;691:45;687:54;679:62;;;;199:548;;;;:::o;752:196::-;820:20;;-1:-1:-1;;;;;869:54:8;;859:65;;849:93;;938:1;935;928:12;953:254;1021:6;1029;1082:2;1070:9;1061:7;1057:23;1053:32;1050:52;;;1098:1;1095;1088:12;1050:52;1121:29;1140:9;1121:29;:::i;:::-;1111:39;1197:2;1182:18;;;;1169:32;;-1:-1:-1;;;953:254:8:o;1586:328::-;1663:6;1671;1679;1732:2;1720:9;1711:7;1707:23;1703:32;1700:52;;;1748:1;1745;1738:12;1700:52;1771:29;1790:9;1771:29;:::i;:::-;1761:39;;1819:38;1853:2;1842:9;1838:18;1819:38;:::i;:::-;1809:48;;1904:2;1893:9;1889:18;1876:32;1866:42;;1586:328;;;;;:::o;2108:186::-;2167:6;2220:2;2208:9;2199:7;2195:23;2191:32;2188:52;;;2236:1;2233;2226:12;2188:52;2259:29;2278:9;2259:29;:::i;2530:184::-;-1:-1:-1;;;2579:1:8;2572:88;2679:4;2676:1;2669:15;2703:4;2700:1;2693:15;2719:922;2788:6;2841:2;2829:9;2820:7;2816:23;2812:32;2809:52;;;2857:1;2854;2847:12;2809:52;2897:9;2884:23;2926:18;2967:2;2959:6;2956:14;2953:34;;;2983:1;2980;2973:12;2953:34;3021:6;3010:9;3006:22;2996:32;;3066:7;3059:4;3055:2;3051:13;3047:27;3037:55;;3088:1;3085;3078:12;3037:55;3124:2;3111:16;3146:2;3142;3139:10;3136:36;;;3152:18;;:::i;:::-;3227:2;3221:9;3195:2;3281:13;;-1:-1:-1;;3277:22:8;;;3301:2;3273:31;3269:40;3257:53;;;3325:18;;;3345:22;;;3322:46;3319:72;;;3371:18;;:::i;:::-;3411:10;3407:2;3400:22;3446:2;3438:6;3431:18;3486:7;3481:2;3476;3472;3468:11;3464:20;3461:33;3458:53;;;3507:1;3504;3497:12;3458:53;3563:2;3558;3554;3550:11;3545:2;3537:6;3533:15;3520:46;3608:1;3586:15;;;3603:2;3582:24;3575:35;;;;-1:-1:-1;3590:6:8;2719:922;-1:-1:-1;;;;;2719:922:8:o;3646:260::-;3714:6;3722;3775:2;3763:9;3754:7;3750:23;3746:32;3743:52;;;3791:1;3788;3781:12;3743:52;3814:29;3833:9;3814:29;:::i;:::-;3804:39;;3862:38;3896:2;3885:9;3881:18;3862:38;:::i;:::-;3852:48;;3646:260;;;;;:::o;3911:437::-;3990:1;3986:12;;;;4033;;;4054:61;;4108:4;4100:6;4096:17;4086:27;;4054:61;4161:2;4153:6;4150:14;4130:18;4127:38;4124:218;;-1:-1:-1;;;4195:1:8;4188:88;4299:4;4296:1;4289:15;4327:4;4324:1;4317:15;4124:218;;3911:437;;;:::o;4353:184::-;-1:-1:-1;;;4402:1:8;4395:88;4502:4;4499:1;4492:15;4526:4;4523:1;4516:15;4542:128;4609:9;;;4630:11;;;4627:37;;;4644:18;;:::i;4675:125::-;4740:9;;;4761:10;;;4758:36;;;4774:18;;:::i;4805:274::-;4845:1;4871;4861:189;;-1:-1:-1;;;4903:1:8;4896:88;5007:4;5004:1;4997:15;5035:4;5032:1;5025:15;4861:189;-1:-1:-1;5064:9:8;;4805:274::o;5616:545::-;5718:2;5713:3;5710:11;5707:448;;;5754:1;5779:5;5775:2;5768:17;5824:4;5820:2;5810:19;5894:2;5882:10;5878:19;5875:1;5871:27;5865:4;5861:38;5930:4;5918:10;5915:20;5912:47;;;-1:-1:-1;5953:4:8;5912:47;6008:2;6003:3;5999:12;5996:1;5992:20;5986:4;5982:31;5972:41;;6063:82;6081:2;6074:5;6071:13;6063:82;;;6126:17;;;6107:1;6096:13;6063:82;;;6067:3;;;5616:545;;;:::o;6337:1352::-;6463:3;6457:10;6490:18;6482:6;6479:30;6476:56;;;6512:18;;:::i;:::-;6541:97;6631:6;6591:38;6623:4;6617:11;6591:38;:::i;:::-;6585:4;6541:97;:::i;:::-;6693:4;;6757:2;6746:14;;6774:1;6769:663;;;;7476:1;7493:6;7490:89;;;-1:-1:-1;7545:19:8;;;7539:26;7490:89;-1:-1:-1;;6294:1:8;6290:11;;;6286:24;6282:29;6272:40;6318:1;6314:11;;;6269:57;7592:81;;6739:944;;6769:663;5563:1;5556:14;;;5600:4;5587:18;;-1:-1:-1;;6805:20:8;;;6923:236;6937:7;6934:1;6931:14;6923:236;;;7026:19;;;7020:26;7005:42;;7118:27;;;;7086:1;7074:14;;;;6953:19;;6923:236;;;6927:3;7187:6;7178:7;7175:19;7172:201;;;7248:19;;;7242:26;-1:-1:-1;;7331:1:8;7327:14;;;7343:3;7323:24;7319:37;7315:42;7300:58;7285:74;;7172:201;-1:-1:-1;;;;;7419:1:8;7403:14;;;7399:22;7386:36;;-1:-1:-1;6337:1352:8:o;9630:168::-;9703:9;;;9734;;9751:15;;;9745:22;;9731:37;9721:71;;9772:18;;:::i","linkReferences":{},"cborAuxdata":{"1":{"value":"0xa2646970667358221220f0883b06564851f25c2214f07da7f7c972f341f687d3de12c8903d945027bfe064736f6c63430008110033","offset":8196}},"immutableReferences":{"860":[{"start":994,"length":32}],"862":[{"start":1305,"length":32}],"888":[{"start":1228,"length":32}],"890":[{"start":947,"length":32}],"1852":[{"start":2844,"length":32},{"start":5002,"length":32},{"start":5180,"length":32},{"start":5313,"length":32},{"start":5418,"length":32},{"start":6803,"length":32}]},"transformations":[{"id":"860","type":"replace","offset":994,"reason":"immutable"},{"id":"862","type":"replace","offset":1305,"reason":"immutable"},{"id":"888","type":"replace","offset":1228,"reason":"immutable"},{"id":"890","type":"replace","offset":947,"reason":"immutable"},{"id":"1852","type":"replace","offset":2844,"reason":"immutable"},{"id":"1852","type":"replace","offset":5002,"reason":"immutable"},{"id":"1852","type":"replace","offset":5180,"reason":"immutable"},{"id":"1852","type":"replace","offset":5313,"reason":"immutable"},{"id":"1852","type":"replace","offset":5418,"reason":"immutable"},{"id":"1852","type":"replace","offset":6803,"reason":"immutable"}],"transformationValues":{"immutables":{"860":"0x000000000000000000000000000000000000000000000000000000003f00de81","862":"0x0000000000000000000000000000000000000000000000000000000000000000","888":"0x000000000000000000000000157ae92276501b73b1a17d226bb89875d6eaafd1","890":"0x0000000000000000000000000000000000000000000000000000000000000012","1852":"0x0000000000000000000000000000000000000000000000000000000000000000"}}},"deployment":{"transactionHash":"0x17c3fc3c56188e75b10fdf0a7c9ffae451888eae3d33118122b8c44dc9c887f3","blockNumber":"37438389","transactionIndex":"176","deployer":"0x157Ae92276501b73b1a17d226BB89875D6eAafD1"},"sources":{"contracts/DefiV3Token.sol":{"content":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.17;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { LibCommon } from \"./lib/LibCommon.sol\";\nimport { ReflectiveERC20 } from \"./ReflectiveERC20.sol\";\n\n/// @title A Defi Token implementation with extended functionalities\n/// @notice Implements ERC20 standards with additional features like tax and deflation\ncontract DefiV3Token is ReflectiveERC20, Ownable {\n  // Constants\n  uint256 private constant MAX_BPS_AMOUNT = 10_000;\n  uint256 private constant MAX_ALLOWED_BPS = 2_000;\n  string public constant VERSION = \"defi_v_3\";\n\n  // State Variables\n  string public initialDocumentUri;\n  string public documentUri;\n  uint256 public immutable initialSupply;\n  uint256 public immutable initialMaxTokenAmountPerAddress;\n  uint256 public maxTokenAmountPerAddress;\n  uint256 public maxTotalSupply;\n\n  /// @notice Configuration properties for the ERC20 token\n  struct ERC20ConfigProps {\n    bool _isMintable;\n    bool _isBurnable;\n    bool _isDocumentAllowed;\n    bool _isMaxAmountOfTokensSet;\n    bool _isMaxSupplySet;\n    bool _isTaxable;\n    bool _isDeflationary;\n    bool _isReflective;\n  }\n  ERC20ConfigProps private configProps;\n\n  address public immutable initialTokenOwner;\n  uint8 private immutable _decimals;\n  address public taxAddress;\n  uint256 public taxBPS;\n  uint256 public deflationBPS;\n\n  // Events\n  event DocumentUriSet(string newDocUri);\n  event MaxTokenAmountPerSet(uint256 newMaxTokenAmount);\n  event TaxConfigSet(address indexed _taxAddress, uint256 indexed _taxBPS);\n  event DeflationConfigSet(uint256 indexed _deflationBPS);\n  event ReflectionConfigSet(uint256 indexed _feeBPS);\n\n  // Custom Errors\n  error InvalidMaxTokenAmount(uint256 maxTokenAmount);\n  error InvalidDecimals(uint8 decimals);\n  error MaxTokenAmountPerAddrLtPrevious();\n  error DestBalanceExceedsMaxAllowed(address addr);\n  error DocumentUriNotAllowed();\n  error MaxTokenAmountNotAllowed();\n  error TokenIsNotTaxable();\n  error TokenIsNotDeflationary();\n  error InvalidTotalBPS(uint256 bps);\n  error InvalidReflectiveConfig();\n  error InvalidMaxSupplyConfig();\n  error TotalSupplyExceedsMaxAllowedAmount();\n\n  /// @notice Constructor to initialize the DeFi token\n  /// @param name_ Name of the token\n  /// @param symbol_ Symbol of the token\n  /// @param initialSupplyToSet Initial supply of tokens\n  /// @param decimalsToSet Number of decimals for the token\n  /// @param tokenOwner Address of the initial token owner\n  /// @param customConfigProps Configuration properties for the token\n  /// @param newDocumentUri URI for the document associated with the token\n  /// @param _taxAddress Address where tax will be sent\n  /// @param bpsParams array of BPS values in this order:\n  ///           taxBPS = bpsParams[0],\n  ///           deflationBPS = bpsParams[1],\n  ///           rewardFeeBPS = bpsParams[2],\n  /// @param amountParams array of amounts for amount specific config:\n  ///           maxTokenAmount = amountParams[0], Maximum token amount per address\n  ///           maxSupplyAmount = amountParams[1], Maximum token token supply amount\n\n  constructor(\n    string memory name_,\n    string memory symbol_,\n    uint256 initialSupplyToSet,\n    uint8 decimalsToSet,\n    address tokenOwner,\n    ERC20ConfigProps memory customConfigProps,\n    string memory newDocumentUri,\n    address _taxAddress,\n    uint256[3] memory bpsParams,\n    uint256[2] memory amountParams\n  )\n    ReflectiveERC20(\n      name_,\n      symbol_,\n      tokenOwner,\n      initialSupplyToSet,\n      decimalsToSet,\n      initialSupplyToSet != 0 ? bpsParams[2] : 0,\n      customConfigProps._isReflective\n    )\n  {\n    // reflection feature can't be used in combination with burning/minting/deflation\n    // or reflection config is invalid if no reflection BPS amount is provided\n    if (\n      (customConfigProps._isReflective &&\n        (customConfigProps._isBurnable ||\n          customConfigProps._isMintable ||\n          customConfigProps._isDeflationary)) ||\n      (!customConfigProps._isReflective && bpsParams[2] != 0)\n    ) {\n      revert InvalidReflectiveConfig();\n    }\n\n    if (customConfigProps._isMaxAmountOfTokensSet) {\n      if (amountParams[0] == 0) {\n        revert InvalidMaxTokenAmount(amountParams[0]);\n      }\n    }\n    if (decimalsToSet > 18) {\n      revert InvalidDecimals(decimalsToSet);\n    }\n\n    if (\n      customConfigProps._isMaxSupplySet &&\n      (!customConfigProps._isMintable || (totalSupply() > amountParams[1]))\n    ) {\n      revert InvalidMaxSupplyConfig();\n    }\n\n    bpsInitChecks(customConfigProps, bpsParams, _taxAddress);\n\n    LibCommon.validateAddress(tokenOwner);\n\n    taxAddress = _taxAddress;\n\n    taxBPS = bpsParams[0];\n    deflationBPS = bpsParams[1];\n    initialSupply = initialSupplyToSet;\n    initialMaxTokenAmountPerAddress = amountParams[0];\n    initialDocumentUri = newDocumentUri;\n    initialTokenOwner = tokenOwner;\n    _decimals = decimalsToSet;\n    configProps = customConfigProps;\n    documentUri = newDocumentUri;\n    maxTokenAmountPerAddress = amountParams[0];\n    maxTotalSupply = amountParams[1];\n\n    if (tokenOwner != msg.sender) {\n      transferOwnership(tokenOwner);\n    }\n  }\n\n  function bpsInitChecks(\n    ERC20ConfigProps memory customConfigProps,\n    uint256[3] memory bpsParams,\n    address _taxAddress\n  ) private pure {\n    uint256 totalBPS = 0;\n    if (customConfigProps._isTaxable) {\n      LibCommon.validateAddress(_taxAddress);\n\n      totalBPS += bpsParams[0];\n    }\n    if (customConfigProps._isDeflationary) {\n      totalBPS += bpsParams[1];\n    }\n    if (customConfigProps._isReflective) {\n      totalBPS += bpsParams[2];\n    }\n    if (totalBPS > MAX_ALLOWED_BPS) {\n      revert InvalidTotalBPS(totalBPS);\n    }\n  }\n\n  // Public and External Functions\n\n  /// @notice Checks if the token is mintable\n  /// @return True if the token can be minted\n  function isMintable() public view returns (bool) {\n    return configProps._isMintable;\n  }\n\n  /// @notice Checks if the token is burnable\n  /// @return True if the token can be burned\n  function isBurnable() public view returns (bool) {\n    return configProps._isBurnable;\n  }\n\n  /// @notice Checks if the maximum amount of tokens per address is set\n  /// @return True if there is a maximum limit for token amount per address\n  function isMaxAmountOfTokensSet() public view returns (bool) {\n    return configProps._isMaxAmountOfTokensSet;\n  }\n\n  /// @notice Checks if the maximum amount of token supply is set\n  /// @return True if there is a maximum limit for token supply\n  function isMaxSupplySet() public view returns (bool) {\n    return configProps._isMaxSupplySet;\n  }\n\n  /// @notice Checks if setting a document URI is allowed\n  /// @return True if setting a document URI is allowed\n  function isDocumentUriAllowed() public view returns (bool) {\n    return configProps._isDocumentAllowed;\n  }\n\n  /// @notice Returns the number of decimals used for the token\n  /// @return The number of decimals\n  function decimals() public view virtual override returns (uint8) {\n    return _decimals;\n  }\n\n  /// @notice Checks if the token is taxable\n  /// @return True if the token has tax applied on transfers\n  function isTaxable() public view returns (bool) {\n    return configProps._isTaxable;\n  }\n\n  /// @notice Checks if the token is deflationary\n  /// @return True if the token has deflation applied on transfers\n  function isDeflationary() public view returns (bool) {\n    return configProps._isDeflationary;\n  }\n\n  /// @notice Checks if the token is reflective\n  /// @return True if the token has reflection (ie. holder rewards) applied on transfers\n  function isReflective() public view returns (bool) {\n    return configProps._isReflective;\n  }\n\n  /// @notice Sets a new document URI\n  /// @dev Can only be called by the contract owner\n  /// @param newDocumentUri The new URI to be set\n  function setDocumentUri(string memory newDocumentUri) external onlyOwner {\n    if (!isDocumentUriAllowed()) {\n      revert DocumentUriNotAllowed();\n    }\n    documentUri = newDocumentUri;\n    emit DocumentUriSet(newDocumentUri);\n  }\n\n  /// @notice Sets a new maximum token amount per address\n  /// @dev Can only be called by the contract owner\n  /// @param newMaxTokenAmount The new maximum token amount per address\n  function setMaxTokenAmountPerAddress(\n    uint256 newMaxTokenAmount\n  ) external onlyOwner {\n    if (!isMaxAmountOfTokensSet()) {\n      revert MaxTokenAmountNotAllowed();\n    }\n    if (newMaxTokenAmount <= maxTokenAmountPerAddress) {\n      revert MaxTokenAmountPerAddrLtPrevious();\n    }\n\n    maxTokenAmountPerAddress = newMaxTokenAmount;\n    emit MaxTokenAmountPerSet(newMaxTokenAmount);\n  }\n\n  /// @notice Sets a new reflection fee\n  /// @dev Can only be called by the contract owner\n  /// @param _feeBPS The reflection fee in basis points\n  function setReflectionConfig(uint256 _feeBPS) external onlyOwner {\n    if (!isReflective()) {\n      revert TokenIsNotReflective();\n    }\n    super._setReflectionFee(_feeBPS);\n\n    emit ReflectionConfigSet(_feeBPS);\n  }\n\n  /// @notice Sets a new tax configuration\n  /// @dev Can only be called by the contract owner\n  /// @param _taxAddress The address where tax will be sent\n  /// @param _taxBPS The tax rate in basis points\n  function setTaxConfig(\n    address _taxAddress,\n    uint256 _taxBPS\n  ) external onlyOwner {\n    if (!isTaxable()) {\n      revert TokenIsNotTaxable();\n    }\n\n    uint256 totalBPS = deflationBPS + tFeeBPS + _taxBPS;\n    if (totalBPS > MAX_ALLOWED_BPS) {\n      revert InvalidTotalBPS(totalBPS);\n    }\n    LibCommon.validateAddress(_taxAddress);\n    taxAddress = _taxAddress;\n    taxBPS = _taxBPS;\n    emit TaxConfigSet(_taxAddress, _taxBPS);\n  }\n\n  /// @notice Sets a new deflation configuration\n  /// @dev Can only be called by the contract owner\n  /// @param _deflationBPS The deflation rate in basis points\n  function setDeflationConfig(uint256 _deflationBPS) external onlyOwner {\n    if (!isDeflationary()) {\n      revert TokenIsNotDeflationary();\n    }\n    uint256 totalBPS = deflationBPS + tFeeBPS + _deflationBPS;\n    if (totalBPS > MAX_ALLOWED_BPS) {\n      revert InvalidTotalBPS(totalBPS);\n    }\n    deflationBPS = _deflationBPS;\n    emit DeflationConfigSet(_deflationBPS);\n  }\n\n  /// @notice Transfers tokens to a specified address\n  /// @dev Overrides the ERC20 transfer function with added tax and deflation logic\n  /// @param to The address to transfer tokens to\n  /// @param amount The amount of tokens to be transferred\n  /// @return True if the transfer was successful\n  function transfer(\n    address to,\n    uint256 amount\n  ) public virtual override returns (bool) {\n    uint256 taxAmount = _taxAmount(msg.sender, amount);\n    uint256 deflationAmount = _deflationAmount(amount);\n    uint256 amountToTransfer = amount - taxAmount - deflationAmount;\n\n    if (isMaxAmountOfTokensSet()) {\n      if (balanceOf(to) + amountToTransfer > maxTokenAmountPerAddress) {\n        revert DestBalanceExceedsMaxAllowed(to);\n      }\n    }\n\n    if (taxAmount != 0) {\n      _transferNonReflectedTax(msg.sender, taxAddress, taxAmount);\n    }\n    if (deflationAmount != 0) {\n      _burn(msg.sender, deflationAmount);\n    }\n    return super.transfer(to, amountToTransfer);\n  }\n\n  /// @notice Transfers tokens from one address to another\n  /// @dev Overrides the ERC20 transferFrom function with added tax and deflation logic\n  /// @param from The address which you want to send tokens from\n  /// @param to The address which you want to transfer to\n  /// @param amount The amount of tokens to be transferred\n  /// @return True if the transfer was successful\n  function transferFrom(\n    address from,\n    address to,\n    uint256 amount\n  ) public virtual override returns (bool) {\n    uint256 taxAmount = _taxAmount(from, amount);\n    uint256 deflationAmount = _deflationAmount(amount);\n    uint256 amountToTransfer = amount - taxAmount - deflationAmount;\n\n    if (isMaxAmountOfTokensSet()) {\n      if (balanceOf(to) + amountToTransfer > maxTokenAmountPerAddress) {\n        revert DestBalanceExceedsMaxAllowed(to);\n      }\n    }\n\n    if (taxAmount != 0) {\n      _transferNonReflectedTax(from, taxAddress, taxAmount);\n    }\n    if (deflationAmount != 0) {\n      _burn(from, deflationAmount);\n    }\n\n    return super.transferFrom(from, to, amountToTransfer);\n  }\n\n  /// @notice Mints new tokens to a specified address\n  /// @dev Can only be called by the contract owner and if minting is enabled\n  /// @param to The address to mint tokens to\n  /// @param amount The amount of tokens to mint\n  function mint(address to, uint256 amount) external onlyOwner {\n    if (!isMintable()) {\n      revert MintingNotEnabled();\n    }\n    if (isMaxAmountOfTokensSet()) {\n      if (balanceOf(to) + amount > maxTokenAmountPerAddress) {\n        revert DestBalanceExceedsMaxAllowed(to);\n      }\n    }\n    if (isMaxSupplySet()) {\n      if (totalSupply() + amount > maxTotalSupply) {\n        revert TotalSupplyExceedsMaxAllowedAmount();\n      }\n    }\n\n    super._mint(to, amount);\n  }\n\n  /// @notice Burns a specific amount of tokens\n  /// @dev Can only be called by the contract owner and if burning is enabled\n  /// @param amount The amount of tokens to be burned\n  function burn(uint256 amount) external onlyOwner {\n    if (!isBurnable()) {\n      revert BurningNotEnabled();\n    }\n    _burn(msg.sender, amount);\n  }\n\n  /// @notice Renounces ownership of the contract\n  /// @dev Leaves the contract without an owner, disabling any functions that require the owner's authorization\n  function renounceOwnership() public override onlyOwner {\n    super.renounceOwnership();\n  }\n\n  /// @notice Transfers ownership of the contract to a new account\n  /// @dev Can only be called by the current owner\n  /// @param newOwner The address of the new owner\n  function transferOwnership(address newOwner) public override onlyOwner {\n    super.transferOwnership(newOwner);\n  }\n\n  // Internal Functions\n\n  /// @notice Calculates the tax amount for a transfer\n  /// @param sender The address initiating the transfer\n  /// @param amount The amount of tokens being transferred\n  /// @return taxAmount The calculated tax amount\n  function _taxAmount(\n    address sender,\n    uint256 amount\n  ) internal view returns (uint256 taxAmount) {\n    taxAmount = 0;\n    if (taxBPS != 0 && sender != taxAddress) {\n      taxAmount = (amount * taxBPS) / MAX_BPS_AMOUNT;\n    }\n  }\n\n  /// @notice Calculates the deflation amount for a transfer\n  /// @param amount The amount of tokens being transferred\n  /// @return deflationAmount The calculated deflation amount\n  function _deflationAmount(\n    uint256 amount\n  ) internal view returns (uint256 deflationAmount) {\n    deflationAmount = 0;\n    if (deflationBPS != 0) {\n      deflationAmount = (amount * deflationBPS) / MAX_BPS_AMOUNT;\n    }\n  }\n}\n"},"contracts/lib/LibCommon.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nlibrary LibCommon {\n  /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n  /*                       CUSTOM ERRORS                        */\n  /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n  /// @dev The ETH transfer has failed.\n  error ETHTransferFailed();\n\n  /// @dev The address is the zero address.\n  error ZeroAddress();\n\n  /// @notice raised when an ERC20 transfer fails\n  error TransferFailed();\n\n  /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n  /*                       ETH OPERATIONS                       */\n  /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n  /// @notice Taken from Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)\n  /// @dev Sends `amount` (in wei) ETH to `to`.\n  /// Reverts upon failure.\n  function safeTransferETH(address to, uint256 amount) internal {\n    // solhint-disable-next-line no-inline-assembly\n    assembly {\n      // Transfer the ETH and check if it succeeded or not.\n      if iszero(call(gas(), to, amount, 0, 0, 0, 0)) {\n        // Store the function selector of `ETHTransferFailed()`.\n        // bytes4(keccak256(bytes(\"ETHTransferFailed()\"))) = 0xb12d13eb\n        mstore(0x00, 0xb12d13eb)\n        // Revert with (offset, size).\n        revert(0x1c, 0x04)\n      }\n    }\n  }\n\n  /// @notice Validates that the address is not the zero address using assembly.\n  /// @dev Reverts if the address is the zero address.\n  function validateAddress(address addr) internal pure {\n    // solhint-disable-next-line no-inline-assembly\n    assembly {\n      if iszero(shl(96, addr)) {\n        // Store the function selector of `ZeroAddress()`.\n        // bytes4(keccak256(bytes(\"ZeroAddress()\"))) = 0xd92e233d\n        mstore(0x00, 0xd92e233d)\n        // Revert with (offset, size).\n        revert(0x1c, 0x04)\n      }\n    }\n  }\n\n  /// @notice Helper function to transfer ERC20 tokens without the need for SafeERC20.\n  /// @dev Reverts if the ERC20 transfer fails.\n  /// @param tokenAddress The address of the ERC20 token.\n  /// @param from The address to transfer the tokens from.\n  /// @param to The address to transfer the tokens to.\n  /// @param amount The amount of tokens to transfer.\n  function safeTransferFrom(\n    address tokenAddress,\n    address from,\n    address to,\n    uint256 amount\n  ) internal returns (bool) {\n    // solhint-disable-next-line avoid-low-level-calls\n    (bool success, bytes memory data) = tokenAddress.call(\n      abi.encodeWithSignature(\n        \"transferFrom(address,address,uint256)\",\n        from,\n        to,\n        amount\n      )\n    );\n    if (!success) {\n      if (data.length != 0) {\n        // bubble up error\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n          let returndata_size := mload(data)\n          revert(add(32, data), returndata_size)\n        }\n      } else {\n        revert TransferFailed();\n      }\n    }\n    return true;\n  }\n\n  /// @notice Helper function to transfer ERC20 tokens without the need for SafeERC20.\n  /// @dev Reverts if the ERC20 transfer fails.\n  /// @param tokenAddress The address of the ERC20 token.\n  /// @param to The address to transfer the tokens to.\n  /// @param amount The amount of tokens to transfer.\n  function safeTransfer(\n    address tokenAddress,\n    address to,\n    uint256 amount\n  ) internal returns (bool) {\n    // solhint-disable-next-line avoid-low-level-calls\n    (bool success, bytes memory data) = tokenAddress.call(\n      abi.encodeWithSignature(\"transfer(address,uint256)\", to, amount)\n    );\n    if (!success) {\n      if (data.length != 0) {\n        // bubble up error\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n          let returndata_size := mload(data)\n          revert(add(32, data), returndata_size)\n        }\n      } else {\n        revert TransferFailed();\n      }\n    }\n    return true;\n  }\n}\n"},"contracts/ReflectiveERC20.sol":{"content":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.17;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { LibCommon } from \"./lib/LibCommon.sol\";\n\n/// @title A ERC20 implementation with extended reflection token functionalities\n/// @notice Implements ERC20 standards with additional token holder reward feature\nabstract contract ReflectiveERC20 is ERC20 {\n  // Constants\n  uint256 private constant BPS_DIVISOR = 10_000;\n\n  mapping(address => uint256) private _rOwned;\n  mapping(address => uint256) private _tOwned;\n\n  uint256 private constant UINT_256_MAX = type(uint256).max;\n  uint256 private _rTotal;\n  uint256 private _tFeeTotal;\n\n  uint256 public tFeeBPS;\n  bool private immutable isReflective;\n\n  // custom errors\n  error TokenIsNotReflective();\n  error TotalReflectionTooSmall();\n  error ZeroTransferError();\n  error MintingNotEnabled();\n  error BurningNotEnabled();\n  error ERC20InsufficientBalance(\n    address recipient,\n    uint256 fromBalance,\n    uint256 balance\n  );\n\n  /// @notice Gets total supply of the erc20 token\n  /// @return Token total supply\n  function _tTotal() public view virtual returns (uint256) {\n    return totalSupply();\n  }\n\n  /// @notice Constructor to initialize the ReflectionErc20 token\n  /// @param name_ Name of the token\n  /// @param symbol_ Symbol of the token\n  /// @param tokenOwner Address of the token owner\n  /// @param totalSupply_ Initial total supply\n  /// @param decimalsToSet Token decimal number\n  /// @param decimalsToSet Token reward (reflection fee BPS value\n  constructor(\n    string memory name_,\n    string memory symbol_,\n    address tokenOwner,\n    uint256 totalSupply_,\n    uint8 decimalsToSet,\n    uint256 tFeeBPS_,\n    bool isReflective_\n  ) ERC20(name_, symbol_) {\n    if (totalSupply_ != 0) {\n      super._mint(tokenOwner, totalSupply_ * 10 ** decimalsToSet);\n      _rTotal = (UINT_256_MAX - (UINT_256_MAX % totalSupply_));\n    }\n\n    _rOwned[tokenOwner] = _rTotal;\n    tFeeBPS = tFeeBPS_;\n    isReflective = isReflective_;\n  }\n\n  // public standard ERC20 functions\n\n  /// @notice Gets balance the erc20 token for specific address\n  /// @param account Account address\n  /// @return Token balance\n  function balanceOf(address account) public view override returns (uint256) {\n    if (isReflective) {\n      return tokenFromReflection(_rOwned[account]);\n    } else {\n      return super.balanceOf(account);\n    }\n  }\n\n  /// @notice Transfers allowed tokens between accounts\n  /// @param from From account\n  /// @param to To account\n  /// @param value Transferred value\n  /// @return Success\n  function transferFrom(\n    address from,\n    address to,\n    uint256 value\n  ) public virtual override returns (bool) {\n    address spender = super._msgSender();\n    _spendAllowance(from, spender, value);\n    _transfer(from, to, value);\n    return true;\n  }\n\n  /// @notice Transfers tokens from owner to an account\n  /// @param to To account\n  /// @param value Transferred value\n  /// @return Success\n  function transfer(\n    address to,\n    uint256 value\n  ) public virtual override returns (bool) {\n    address owner = super._msgSender();\n    _transfer(owner, to, value);\n    return true;\n  }\n\n  // override internal OZ standard ERC20 functions related to transfer\n\n  /// @notice Transfers tokens from owner to an account\n  /// @param to To account\n  /// @param amount Transferred amount\n  function _transfer(\n    address from,\n    address to,\n    uint256 amount\n  ) internal override {\n    if (isReflective) {\n      LibCommon.validateAddress(from);\n      LibCommon.validateAddress(to);\n      if (amount == 0) {\n        revert ZeroTransferError();\n      }\n\n      _transferReflected(from, to, amount);\n    } else {\n      super._transfer(from, to, amount);\n    }\n  }\n\n  // override incompatible internal OZ standard ERC20 functions to disable them in case\n  // reflection mechanism is used, ie. tFeeBPS is non zero\n\n  /// @notice Creates specified amount of tokens, it either uses standard OZ ERC function\n  ///         or in case of reflection logic, it is prohibited\n  /// @param account Account new tokens will be transferred to\n  /// @param value Created tokens value\n  function _mint(address account, uint256 value) internal override {\n    if (isReflective) {\n      revert MintingNotEnabled();\n    } else {\n      super._mint(account, value);\n    }\n  }\n\n  /// @notice Destroys specified amount of tokens, it either uses standard OZ ERC function\n  ///         or in case of reflection logic, it is prohibited\n  /// @param account Account in which tokens will be destroyed\n  /// @param value Destroyed tokens value\n  function _burn(address account, uint256 value) internal override {\n    if (isReflective) {\n      revert BurningNotEnabled();\n    } else {\n      super._burn(account, value);\n    }\n  }\n\n  // public reflection custom functions\n\n  /// @notice Sets a new reflection fee\n  /// @dev Should only be called by the contract owner\n  /// @param _tFeeBPS The reflection fee in basis points\n  function _setReflectionFee(uint256 _tFeeBPS) internal {\n    if (!isReflective) {\n      revert TokenIsNotReflective();\n    }\n\n    tFeeBPS = _tFeeBPS;\n  }\n\n  /// @notice Calculates number of tokens from reflection amount\n  /// @param rAmount Reflection token amount\n  function tokenFromReflection(uint256 rAmount) public view returns (uint256) {\n    if (rAmount > _rTotal) {\n      revert TotalReflectionTooSmall();\n    }\n\n    uint256 currentRate = _getRate();\n    return rAmount / currentRate;\n  }\n\n  // private reflection custom functions\n\n  /// @notice Transfers reflected amount of tokens\n  /// @param sender Account to transfer tokens from\n  /// @param recipient Account to transfer tokens to\n  /// @param tAmount Total token amount\n  function _transferReflected(\n    address sender,\n    address recipient,\n    uint256 tAmount\n  ) private {\n    uint256 tFee = calculateFee(tAmount);\n    uint256 tTransferAmount = tAmount - tFee;\n    (uint256 rAmount, uint256 rFee, uint256 rTransferAmount) = _getRValues(\n      tAmount,\n      tFee,\n      tTransferAmount\n    );\n\n    if (tAmount != 0) {\n      _rUpdate(sender, recipient, rAmount, rTransferAmount);\n\n      _reflectFee(rFee, tFee);\n      emit Transfer(sender, recipient, tAmount);\n    }\n  }\n\n  /// @notice Deducts reflection fee from reflection supply to 'distribute' token holder rewards\n  /// @param rFee Reflection fee\n  /// @param tFee Token fee\n  function _reflectFee(uint256 rFee, uint256 tFee) private {\n    _rTotal = _rTotal - rFee;\n    _tFeeTotal = _tFeeTotal + tFee;\n  }\n\n  /// @notice Calculates the reflection fee from token amount\n  /// @param _amount Amount of tokens to calculate fee from\n  function calculateFee(uint256 _amount) private view returns (uint256) {\n    return (_amount * tFeeBPS) / BPS_DIVISOR;\n  }\n\n  /// @notice Transfers Tax related tokens and do not apply reflection fees\n  /// @param from Account to transfer tokens from\n  /// @param to Account to transfer tokens to\n  /// @param tAmount Total token amount\n  function _transferNonReflectedTax(\n    address from,\n    address to,\n    uint256 tAmount\n  ) internal {\n    if (isReflective) {\n      if (tAmount != 0) {\n        uint256 currentRate = _getRate();\n        uint256 rAmount = tAmount * currentRate;\n\n        _rUpdate(from, to, rAmount, rAmount);\n        emit Transfer(from, to, tAmount);\n      }\n    } else {\n      super._transfer(from, to, tAmount);\n    }\n  }\n\n  /// @notice Get reflective values from token values\n  /// @param tAmount Token amount\n  /// @param tFee Token fee\n  /// @param tTransferAmount Transfer amount\n  function _getRValues(\n    uint256 tAmount,\n    uint256 tFee,\n    uint256 tTransferAmount\n  ) private view returns (uint256, uint256, uint256) {\n    uint256 currentRate = _getRate();\n    uint256 rAmount = tAmount * currentRate;\n    uint256 rFee = tFee * currentRate;\n    uint256 rTransferAmount = tTransferAmount * currentRate;\n\n    return (rAmount, rFee, rTransferAmount);\n  }\n\n  /// @notice Get ratio rate between reflective and token supply\n  /// @return Reflective rate\n  function _getRate() private view returns (uint256) {\n    (uint256 rSupply, uint256 tSupply) = _getCurrentSupply();\n    return rSupply / tSupply;\n  }\n\n  /// @notice Get reflective and token supplies\n  /// @return Reflective and token supplies\n  function _getCurrentSupply() private view returns (uint256, uint256) {\n    return (_rTotal, _tTotal());\n  }\n\n  /// @notice Update reflective balances to reflect amount transfer,\n  ///         with or without a fee applied. If a fee is applied,\n  ///         the amount deducted from the sender will differ\n  ///         from amount added to the recipient\n  /// @param sender Sender address\n  /// @param recipient Recipient address\n  /// @param rSubAmount Amount to be deducted from sender\n  /// @param rTransferAmount Amount to be added to recipient\n  function _rUpdate(\n    address sender,\n    address recipient,\n    uint256 rSubAmount,\n    uint256 rTransferAmount\n  ) private {\n    uint256 fromBalance = _rOwned[sender];\n    if (fromBalance < rSubAmount) {\n      revert ERC20InsufficientBalance(recipient, fromBalance, rSubAmount);\n    }\n    _rOwned[sender] = _rOwned[sender] - rSubAmount;\n    _rOwned[recipient] = _rOwned[recipient] + rTransferAmount;\n  }\n}\n"},"@openzeppelin/contracts/utils/Context.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"},"@openzeppelin/contracts/access/Ownable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor() {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"},"@openzeppelin/contracts/token/ERC20/ERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n    mapping(address => uint256) private _balances;\n\n    mapping(address => mapping(address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the default value returned by this function, unless\n     * it's overridden.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual override returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address to, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, amount);\n        _transfer(from, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, allowance(owner, spender) + addedValue);\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        uint256 currentAllowance = allowance(owner, spender);\n        require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n        unchecked {\n            _approve(owner, spender, currentAllowance - subtractedValue);\n        }\n\n        return true;\n    }\n\n    /**\n     * @dev Moves `amount` of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     */\n    function _transfer(address from, address to, uint256 amount) internal virtual {\n        require(from != address(0), \"ERC20: transfer from the zero address\");\n        require(to != address(0), \"ERC20: transfer to the zero address\");\n\n        _beforeTokenTransfer(from, to, amount);\n\n        uint256 fromBalance = _balances[from];\n        require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n        unchecked {\n            _balances[from] = fromBalance - amount;\n            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n            // decrementing then incrementing.\n            _balances[to] += amount;\n        }\n\n        emit Transfer(from, to, amount);\n\n        _afterTokenTransfer(from, to, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply += amount;\n        unchecked {\n            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n            _balances[account] += amount;\n        }\n        emit Transfer(address(0), account, amount);\n\n        _afterTokenTransfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        uint256 accountBalance = _balances[account];\n        require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n        unchecked {\n            _balances[account] = accountBalance - amount;\n            // Overflow not possible: amount <= accountBalance <= totalSupply.\n            _totalSupply -= amount;\n        }\n\n        emit Transfer(account, address(0), amount);\n\n        _afterTokenTransfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(address owner, address spender, uint256 amount) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n     *\n     * Does not update the allowance amount in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Might emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n            unchecked {\n                _approve(owner, spender, currentAllowance - amount);\n            }\n        }\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n    /**\n     * @dev Hook that is called after any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * has been transferred to `to`.\n     * - when `from` is zero, `amount` tokens have been minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n"},"@openzeppelin/contracts/token/ERC20/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n"},"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"}},"compilation":{"language":"Solidity","compiler":"solc","compilerVersion":"0.8.17+commit.8df45f5f","compilerSettings":{"metadata":{"bytecodeHash":"ipfs","useLiteralContent":true},"libraries":{},"optimizer":{"runs":1337,"enabled":true},"evmVersion":"london","remappings":[]},"name":"DefiV3Token","fullyQualifiedName":"contracts/DefiV3Token.sol:DefiV3Token"},"abi":[{"type":"constructor","inputs":[{"name":"name_","type":"string","internalType":"string"},{"name":"symbol_","type":"string","internalType":"string"},{"name":"initialSupplyToSet","type":"uint256","internalType":"uint256"},{"name":"decimalsToSet","type":"uint8","internalType":"uint8"},{"name":"tokenOwner","type":"address","internalType":"address"},{"name":"customConfigProps","type":"tuple","components":[{"name":"_isMintable","type":"bool","internalType":"bool"},{"name":"_isBurnable","type":"bool","internalType":"bool"},{"name":"_isDocumentAllowed","type":"bool","internalType":"bool"},{"name":"_isMaxAmountOfTokensSet","type":"bool","internalType":"bool"},{"name":"_isMaxSupplySet","type":"bool","internalType":"bool"},{"name":"_isTaxable","type":"bool","internalType":"bool"},{"name":"_isDeflationary","type":"bool","internalType":"bool"},{"name":"_isReflective","type":"bool","internalType":"bool"}],"internalType":"struct DefiV3Token.ERC20ConfigProps"},{"name":"newDocumentUri","type":"string","internalType":"string"},{"name":"_taxAddress","type":"address","internalType":"address"},{"name":"bpsParams","type":"uint256[3]","internalType":"uint256[3]"},{"name":"amountParams","type":"uint256[2]","internalType":"uint256[2]"}],"stateMutability":"nonpayable"},{"name":"BurningNotEnabled","type":"error","inputs":[]},{"name":"DestBalanceExceedsMaxAllowed","type":"error","inputs":[{"name":"addr","type":"address","internalType":"address"}]},{"name":"DocumentUriNotAllowed","type":"error","inputs":[]},{"name":"ERC20InsufficientBalance","type":"error","inputs":[{"name":"recipient","type":"address","internalType":"address"},{"name":"fromBalance","type":"uint256","internalType":"uint256"},{"name":"balance","type":"uint256","internalType":"uint256"}]},{"name":"InvalidDecimals","type":"error","inputs":[{"name":"decimals","type":"uint8","internalType":"uint8"}]},{"name":"InvalidMaxSupplyConfig","type":"error","inputs":[]},{"name":"InvalidMaxTokenAmount","type":"error","inputs":[{"name":"maxTokenAmount","type":"uint256","internalType":"uint256"}]},{"name":"InvalidReflectiveConfig","type":"error","inputs":[]},{"name":"InvalidTotalBPS","type":"error","inputs":[{"name":"bps","type":"uint256","internalType":"uint256"}]},{"name":"MaxTokenAmountNotAllowed","type":"error","inputs":[]},{"name":"MaxTokenAmountPerAddrLtPrevious","type":"error","inputs":[]},{"name":"MintingNotEnabled","type":"error","inputs":[]},{"name":"TokenIsNotDeflationary","type":"error","inputs":[]},{"name":"TokenIsNotReflective","type":"error","inputs":[]},{"name":"TokenIsNotTaxable","type":"error","inputs":[]},{"name":"TotalReflectionTooSmall","type":"error","inputs":[]},{"name":"TotalSupplyExceedsMaxAllowedAmount","type":"error","inputs":[]},{"name":"ZeroTransferError","type":"error","inputs":[]},{"name":"Approval","type":"event","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"spender","type":"address","indexed":true,"internalType":"address"},{"name":"value","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"DeflationConfigSet","type":"event","inputs":[{"name":"_deflationBPS","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"DocumentUriSet","type":"event","inputs":[{"name":"newDocUri","type":"string","indexed":false,"internalType":"string"}],"anonymous":false},{"name":"MaxTokenAmountPerSet","type":"event","inputs":[{"name":"newMaxTokenAmount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"OwnershipTransferred","type":"event","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"ReflectionConfigSet","type":"event","inputs":[{"name":"_feeBPS","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"TaxConfigSet","type":"event","inputs":[{"name":"_taxAddress","type":"address","indexed":true,"internalType":"address"},{"name":"_taxBPS","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"Transfer","type":"event","inputs":[{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"value","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"VERSION","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"_tTotal","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"allowance","type":"function","inputs":[{"name":"owner","type":"address","internalType":"address"},{"name":"spender","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"approve","type":"function","inputs":[{"name":"spender","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"name":"balanceOf","type":"function","inputs":[{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"burn","type":"function","inputs":[{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"decimals","type":"function","inputs":[],"outputs":[{"name":"","type":"uint8","internalType":"uint8"}],"stateMutability":"view"},{"name":"decreaseAllowance","type":"function","inputs":[{"name":"spender","type":"address","internalType":"address"},{"name":"subtractedValue","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"name":"deflationBPS","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"documentUri","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"increaseAllowance","type":"function","inputs":[{"name":"spender","type":"address","internalType":"address"},{"name":"addedValue","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"name":"initialDocumentUri","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"initialMaxTokenAmountPerAddress","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"initialSupply","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"initialTokenOwner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"isBurnable","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"isDeflationary","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"isDocumentUriAllowed","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"isMaxAmountOfTokensSet","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"isMaxSupplySet","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"isMintable","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"isReflective","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"isTaxable","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"maxTokenAmountPerAddress","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"maxTotalSupply","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"mint","type":"function","inputs":[{"name":"to","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"name","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"owner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"renounceOwnership","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"setDeflationConfig","type":"function","inputs":[{"name":"_deflationBPS","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setDocumentUri","type":"function","inputs":[{"name":"newDocumentUri","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setMaxTokenAmountPerAddress","type":"function","inputs":[{"name":"newMaxTokenAmount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setReflectionConfig","type":"function","inputs":[{"name":"_feeBPS","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setTaxConfig","type":"function","inputs":[{"name":"_taxAddress","type":"address","internalType":"address"},{"name":"_taxBPS","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"symbol","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"tFeeBPS","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"taxAddress","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"taxBPS","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"tokenFromReflection","type":"function","inputs":[{"name":"rAmount","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"totalSupply","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"transfer","type":"function","inputs":[{"name":"to","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"name":"transferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"name":"transferOwnership","type":"function","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"}],"metadata":{"compiler":{"version":"0.8.17+commit.8df45f5f"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"uint256","name":"initialSupplyToSet","type":"uint256"},{"internalType":"uint8","name":"decimalsToSet","type":"uint8"},{"internalType":"address","name":"tokenOwner","type":"address"},{"components":[{"internalType":"bool","name":"_isMintable","type":"bool"},{"internalType":"bool","name":"_isBurnable","type":"bool"},{"internalType":"bool","name":"_isDocumentAllowed","type":"bool"},{"internalType":"bool","name":"_isMaxAmountOfTokensSet","type":"bool"},{"internalType":"bool","name":"_isMaxSupplySet","type":"bool"},{"internalType":"bool","name":"_isTaxable","type":"bool"},{"internalType":"bool","name":"_isDeflationary","type":"bool"},{"internalType":"bool","name":"_isReflective","type":"bool"}],"internalType":"struct DefiV3Token.ERC20ConfigProps","name":"customConfigProps","type":"tuple"},{"internalType":"string","name":"newDocumentUri","type":"string"},{"internalType":"address","name":"_taxAddress","type":"address"},{"internalType":"uint256[3]","name":"bpsParams","type":"uint256[3]"},{"internalType":"uint256[2]","name":"amountParams","type":"uint256[2]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"BurningNotEnabled","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"DestBalanceExceedsMaxAllowed","type":"error"},{"inputs":[],"name":"DocumentUriNotAllowed","type":"error"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"fromBalance","type":"uint256"},{"internalType":"uint256","name":"balance","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"uint8","name":"decimals","type":"uint8"}],"name":"InvalidDecimals","type":"error"},{"inputs":[],"name":"InvalidMaxSupplyConfig","type":"error"},{"inputs":[{"internalType":"uint256","name":"maxTokenAmount","type":"uint256"}],"name":"InvalidMaxTokenAmount","type":"error"},{"inputs":[],"name":"InvalidReflectiveConfig","type":"error"},{"inputs":[{"internalType":"uint256","name":"bps","type":"uint256"}],"name":"InvalidTotalBPS","type":"error"},{"inputs":[],"name":"MaxTokenAmountNotAllowed","type":"error"},{"inputs":[],"name":"MaxTokenAmountPerAddrLtPrevious","type":"error"},{"inputs":[],"name":"MintingNotEnabled","type":"error"},{"inputs":[],"name":"TokenIsNotDeflationary","type":"error"},{"inputs":[],"name":"TokenIsNotReflective","type":"error"},{"inputs":[],"name":"TokenIsNotTaxable","type":"error"},{"inputs":[],"name":"TotalReflectionTooSmall","type":"error"},{"inputs":[],"name":"TotalSupplyExceedsMaxAllowedAmount","type":"error"},{"inputs":[],"name":"ZeroTransferError","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_deflationBPS","type":"uint256"}],"name":"DeflationConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"newDocUri","type":"string"}],"name":"DocumentUriSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMaxTokenAmount","type":"uint256"}],"name":"MaxTokenAmountPerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_feeBPS","type":"uint256"}],"name":"ReflectionConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_taxAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"_taxBPS","type":"uint256"}],"name":"TaxConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_tTotal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deflationBPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"documentUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialDocumentUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialMaxTokenAmountPerAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialTokenOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isBurnable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isDeflationary","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isDocumentUriAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isMaxAmountOfTokensSet","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isMaxSupplySet","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isMintable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isReflective","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isTaxable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTokenAmountPerAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_deflationBPS","type":"uint256"}],"name":"setDeflationConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newDocumentUri","type":"string"}],"name":"setDocumentUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMaxTokenAmount","type":"uint256"}],"name":"setMaxTokenAmountPerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_feeBPS","type":"uint256"}],"name":"setReflectionConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_taxAddress","type":"address"},{"internalType":"uint256","name":"_taxBPS","type":"uint256"}],"name":"setTaxConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tFeeBPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxBPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"rAmount","type":"uint256"}],"name":"tokenFromReflection","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"kind":"dev","methods":{"_tTotal()":{"returns":{"_0":"Token total supply"}},"allowance(address,address)":{"details":"See {IERC20-allowance}."},"approve(address,uint256)":{"details":"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address."},"balanceOf(address)":{"params":{"account":"Account address"},"returns":{"_0":"Token balance"}},"burn(uint256)":{"details":"Can only be called by the contract owner and if burning is enabled","params":{"amount":"The amount of tokens to be burned"}},"constructor":{"params":{"_taxAddress":"Address where tax will be sent","amountParams":"array of amounts for amount specific config:           maxTokenAmount = amountParams[0], Maximum token amount per address           maxSupplyAmount = amountParams[1], Maximum token token supply amount","bpsParams":"array of BPS values in this order:           taxBPS = bpsParams[0],           deflationBPS = bpsParams[1],           rewardFeeBPS = bpsParams[2],","customConfigProps":"Configuration properties for the token","decimalsToSet":"Number of decimals for the token","initialSupplyToSet":"Initial supply of tokens","name_":"Name of the token","newDocumentUri":"URI for the document associated with the token","symbol_":"Symbol of the token","tokenOwner":"Address of the initial token owner"}},"decimals()":{"returns":{"_0":"The number of decimals"}},"decreaseAllowance(address,uint256)":{"details":"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`."},"increaseAllowance(address,uint256)":{"details":"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address."},"isBurnable()":{"returns":{"_0":"True if the token can be burned"}},"isDeflationary()":{"returns":{"_0":"True if the token has deflation applied on transfers"}},"isDocumentUriAllowed()":{"returns":{"_0":"True if setting a document URI is allowed"}},"isMaxAmountOfTokensSet()":{"returns":{"_0":"True if there is a maximum limit for token amount per address"}},"isMaxSupplySet()":{"returns":{"_0":"True if there is a maximum limit for token supply"}},"isMintable()":{"returns":{"_0":"True if the token can be minted"}},"isReflective()":{"returns":{"_0":"True if the token has reflection (ie. holder rewards) applied on transfers"}},"isTaxable()":{"returns":{"_0":"True if the token has tax applied on transfers"}},"mint(address,uint256)":{"details":"Can only be called by the contract owner and if minting is enabled","params":{"amount":"The amount of tokens to mint","to":"The address to mint tokens to"}},"name()":{"details":"Returns the name of the token."},"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Leaves the contract without an owner, disabling any functions that require the owner's authorization"},"setDeflationConfig(uint256)":{"details":"Can only be called by the contract owner","params":{"_deflationBPS":"The deflation rate in basis points"}},"setDocumentUri(string)":{"details":"Can only be called by the contract owner","params":{"newDocumentUri":"The new URI to be set"}},"setMaxTokenAmountPerAddress(uint256)":{"details":"Can only be called by the contract owner","params":{"newMaxTokenAmount":"The new maximum token amount per address"}},"setReflectionConfig(uint256)":{"details":"Can only be called by the contract owner","params":{"_feeBPS":"The reflection fee in basis points"}},"setTaxConfig(address,uint256)":{"details":"Can only be called by the contract owner","params":{"_taxAddress":"The address where tax will be sent","_taxBPS":"The tax rate in basis points"}},"symbol()":{"details":"Returns the symbol of the token, usually a shorter version of the name."},"tokenFromReflection(uint256)":{"params":{"rAmount":"Reflection token amount"}},"totalSupply()":{"details":"See {IERC20-totalSupply}."},"transfer(address,uint256)":{"details":"Overrides the ERC20 transfer function with added tax and deflation logic","params":{"amount":"The amount of tokens to be transferred","to":"The address to transfer tokens to"},"returns":{"_0":"True if the transfer was successful"}},"transferFrom(address,address,uint256)":{"details":"Overrides the ERC20 transferFrom function with added tax and deflation logic","params":{"amount":"The amount of tokens to be transferred","from":"The address which you want to send tokens from","to":"The address which you want to transfer to"},"returns":{"_0":"True if the transfer was successful"}},"transferOwnership(address)":{"details":"Can only be called by the current owner","params":{"newOwner":"The address of the new owner"}}},"title":"A Defi Token implementation with extended functionalities","version":1},"userdoc":{"kind":"user","methods":{"_tTotal()":{"notice":"Gets total supply of the erc20 token"},"balanceOf(address)":{"notice":"Gets balance the erc20 token for specific address"},"burn(uint256)":{"notice":"Burns a specific amount of tokens"},"constructor":{"notice":"Constructor to initialize the DeFi token"},"decimals()":{"notice":"Returns the number of decimals used for the token"},"isBurnable()":{"notice":"Checks if the token is burnable"},"isDeflationary()":{"notice":"Checks if the token is deflationary"},"isDocumentUriAllowed()":{"notice":"Checks if setting a document URI is allowed"},"isMaxAmountOfTokensSet()":{"notice":"Checks if the maximum amount of tokens per address is set"},"isMaxSupplySet()":{"notice":"Checks if the maximum amount of token supply is set"},"isMintable()":{"notice":"Checks if the token is mintable"},"isReflective()":{"notice":"Checks if the token is reflective"},"isTaxable()":{"notice":"Checks if the token is taxable"},"mint(address,uint256)":{"notice":"Mints new tokens to a specified address"},"renounceOwnership()":{"notice":"Renounces ownership of the contract"},"setDeflationConfig(uint256)":{"notice":"Sets a new deflation configuration"},"setDocumentUri(string)":{"notice":"Sets a new document URI"},"setMaxTokenAmountPerAddress(uint256)":{"notice":"Sets a new maximum token amount per address"},"setReflectionConfig(uint256)":{"notice":"Sets a new reflection fee"},"setTaxConfig(address,uint256)":{"notice":"Sets a new tax configuration"},"tokenFromReflection(uint256)":{"notice":"Calculates number of tokens from reflection amount"},"transfer(address,uint256)":{"notice":"Transfers tokens to a specified address"},"transferFrom(address,address,uint256)":{"notice":"Transfers tokens from one address to another"},"transferOwnership(address)":{"notice":"Transfers ownership of the contract to a new account"}},"notice":"Implements ERC20 standards with additional features like tax and deflation","version":1}},"settings":{"compilationTarget":{"contracts/DefiV3Token.sol":"DefiV3Token"},"evmVersion":"london","libraries":{},"metadata":{"bytecodeHash":"ipfs","useLiteralContent":true},"optimizer":{"enabled":true,"runs":1337},"remappings":[]},"sources":{"@openzeppelin/contracts/access/Ownable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor() {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n","keccak256":"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218","license":"MIT"},"@openzeppelin/contracts/token/ERC20/ERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n    mapping(address => uint256) private _balances;\n\n    mapping(address => mapping(address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the default value returned by this function, unless\n     * it's overridden.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual override returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address to, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, amount);\n        _transfer(from, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, allowance(owner, spender) + addedValue);\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        uint256 currentAllowance = allowance(owner, spender);\n        require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n        unchecked {\n            _approve(owner, spender, currentAllowance - subtractedValue);\n        }\n\n        return true;\n    }\n\n    /**\n     * @dev Moves `amount` of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     */\n    function _transfer(address from, address to, uint256 amount) internal virtual {\n        require(from != address(0), \"ERC20: transfer from the zero address\");\n        require(to != address(0), \"ERC20: transfer to the zero address\");\n\n        _beforeTokenTransfer(from, to, amount);\n\n        uint256 fromBalance = _balances[from];\n        require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n        unchecked {\n            _balances[from] = fromBalance - amount;\n            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n            // decrementing then incrementing.\n            _balances[to] += amount;\n        }\n\n        emit Transfer(from, to, amount);\n\n        _afterTokenTransfer(from, to, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply += amount;\n        unchecked {\n            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n            _balances[account] += amount;\n        }\n        emit Transfer(address(0), account, amount);\n\n        _afterTokenTransfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        uint256 accountBalance = _balances[account];\n        require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n        unchecked {\n            _balances[account] = accountBalance - amount;\n            // Overflow not possible: amount <= accountBalance <= totalSupply.\n            _totalSupply -= amount;\n        }\n\n        emit Transfer(account, address(0), amount);\n\n        _afterTokenTransfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(address owner, address spender, uint256 amount) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n     *\n     * Does not update the allowance amount in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Might emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n            unchecked {\n                _approve(owner, spender, currentAllowance - amount);\n            }\n        }\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n    /**\n     * @dev Hook that is called after any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * has been transferred to `to`.\n     * - when `from` is zero, `amount` tokens have been minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n","keccak256":"0xa56ca923f70c1748830700250b19c61b70db9a683516dc5e216694a50445d99c","license":"MIT"},"@openzeppelin/contracts/token/ERC20/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n","keccak256":"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305","license":"MIT"},"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n","keccak256":"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca","license":"MIT"},"@openzeppelin/contracts/utils/Context.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n","keccak256":"0xa92e4fa126feb6907daa0513ddd816b2eb91f30a808de54f63c17d0e162c3439","license":"MIT"},"contracts/DefiV3Token.sol":{"content":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.17;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { LibCommon } from \"./lib/LibCommon.sol\";\nimport { ReflectiveERC20 } from \"./ReflectiveERC20.sol\";\n\n/// @title A Defi Token implementation with extended functionalities\n/// @notice Implements ERC20 standards with additional features like tax and deflation\ncontract DefiV3Token is ReflectiveERC20, Ownable {\n  // Constants\n  uint256 private constant MAX_BPS_AMOUNT = 10_000;\n  uint256 private constant MAX_ALLOWED_BPS = 2_000;\n  string public constant VERSION = \"defi_v_3\";\n\n  // State Variables\n  string public initialDocumentUri;\n  string public documentUri;\n  uint256 public immutable initialSupply;\n  uint256 public immutable initialMaxTokenAmountPerAddress;\n  uint256 public maxTokenAmountPerAddress;\n  uint256 public maxTotalSupply;\n\n  /// @notice Configuration properties for the ERC20 token\n  struct ERC20ConfigProps {\n    bool _isMintable;\n    bool _isBurnable;\n    bool _isDocumentAllowed;\n    bool _isMaxAmountOfTokensSet;\n    bool _isMaxSupplySet;\n    bool _isTaxable;\n    bool _isDeflationary;\n    bool _isReflective;\n  }\n  ERC20ConfigProps private configProps;\n\n  address public immutable initialTokenOwner;\n  uint8 private immutable _decimals;\n  address public taxAddress;\n  uint256 public taxBPS;\n  uint256 public deflationBPS;\n\n  // Events\n  event DocumentUriSet(string newDocUri);\n  event MaxTokenAmountPerSet(uint256 newMaxTokenAmount);\n  event TaxConfigSet(address indexed _taxAddress, uint256 indexed _taxBPS);\n  event DeflationConfigSet(uint256 indexed _deflationBPS);\n  event ReflectionConfigSet(uint256 indexed _feeBPS);\n\n  // Custom Errors\n  error InvalidMaxTokenAmount(uint256 maxTokenAmount);\n  error InvalidDecimals(uint8 decimals);\n  error MaxTokenAmountPerAddrLtPrevious();\n  error DestBalanceExceedsMaxAllowed(address addr);\n  error DocumentUriNotAllowed();\n  error MaxTokenAmountNotAllowed();\n  error TokenIsNotTaxable();\n  error TokenIsNotDeflationary();\n  error InvalidTotalBPS(uint256 bps);\n  error InvalidReflectiveConfig();\n  error InvalidMaxSupplyConfig();\n  error TotalSupplyExceedsMaxAllowedAmount();\n\n  /// @notice Constructor to initialize the DeFi token\n  /// @param name_ Name of the token\n  /// @param symbol_ Symbol of the token\n  /// @param initialSupplyToSet Initial supply of tokens\n  /// @param decimalsToSet Number of decimals for the token\n  /// @param tokenOwner Address of the initial token owner\n  /// @param customConfigProps Configuration properties for the token\n  /// @param newDocumentUri URI for the document associated with the token\n  /// @param _taxAddress Address where tax will be sent\n  /// @param bpsParams array of BPS values in this order:\n  ///           taxBPS = bpsParams[0],\n  ///           deflationBPS = bpsParams[1],\n  ///           rewardFeeBPS = bpsParams[2],\n  /// @param amountParams array of amounts for amount specific config:\n  ///           maxTokenAmount = amountParams[0], Maximum token amount per address\n  ///           maxSupplyAmount = amountParams[1], Maximum token token supply amount\n\n  constructor(\n    string memory name_,\n    string memory symbol_,\n    uint256 initialSupplyToSet,\n    uint8 decimalsToSet,\n    address tokenOwner,\n    ERC20ConfigProps memory customConfigProps,\n    string memory newDocumentUri,\n    address _taxAddress,\n    uint256[3] memory bpsParams,\n    uint256[2] memory amountParams\n  )\n    ReflectiveERC20(\n      name_,\n      symbol_,\n      tokenOwner,\n      initialSupplyToSet,\n      decimalsToSet,\n      initialSupplyToSet != 0 ? bpsParams[2] : 0,\n      customConfigProps._isReflective\n    )\n  {\n    // reflection feature can't be used in combination with burning/minting/deflation\n    // or reflection config is invalid if no reflection BPS amount is provided\n    if (\n      (customConfigProps._isReflective &&\n        (customConfigProps._isBurnable ||\n          customConfigProps._isMintable ||\n          customConfigProps._isDeflationary)) ||\n      (!customConfigProps._isReflective && bpsParams[2] != 0)\n    ) {\n      revert InvalidReflectiveConfig();\n    }\n\n    if (customConfigProps._isMaxAmountOfTokensSet) {\n      if (amountParams[0] == 0) {\n        revert InvalidMaxTokenAmount(amountParams[0]);\n      }\n    }\n    if (decimalsToSet > 18) {\n      revert InvalidDecimals(decimalsToSet);\n    }\n\n    if (\n      customConfigProps._isMaxSupplySet &&\n      (!customConfigProps._isMintable || (totalSupply() > amountParams[1]))\n    ) {\n      revert InvalidMaxSupplyConfig();\n    }\n\n    bpsInitChecks(customConfigProps, bpsParams, _taxAddress);\n\n    LibCommon.validateAddress(tokenOwner);\n\n    taxAddress = _taxAddress;\n\n    taxBPS = bpsParams[0];\n    deflationBPS = bpsParams[1];\n    initialSupply = initialSupplyToSet;\n    initialMaxTokenAmountPerAddress = amountParams[0];\n    initialDocumentUri = newDocumentUri;\n    initialTokenOwner = tokenOwner;\n    _decimals = decimalsToSet;\n    configProps = customConfigProps;\n    documentUri = newDocumentUri;\n    maxTokenAmountPerAddress = amountParams[0];\n    maxTotalSupply = amountParams[1];\n\n    if (tokenOwner != msg.sender) {\n      transferOwnership(tokenOwner);\n    }\n  }\n\n  function bpsInitChecks(\n    ERC20ConfigProps memory customConfigProps,\n    uint256[3] memory bpsParams,\n    address _taxAddress\n  ) private pure {\n    uint256 totalBPS = 0;\n    if (customConfigProps._isTaxable) {\n      LibCommon.validateAddress(_taxAddress);\n\n      totalBPS += bpsParams[0];\n    }\n    if (customConfigProps._isDeflationary) {\n      totalBPS += bpsParams[1];\n    }\n    if (customConfigProps._isReflective) {\n      totalBPS += bpsParams[2];\n    }\n    if (totalBPS > MAX_ALLOWED_BPS) {\n      revert InvalidTotalBPS(totalBPS);\n    }\n  }\n\n  // Public and External Functions\n\n  /// @notice Checks if the token is mintable\n  /// @return True if the token can be minted\n  function isMintable() public view returns (bool) {\n    return configProps._isMintable;\n  }\n\n  /// @notice Checks if the token is burnable\n  /// @return True if the token can be burned\n  function isBurnable() public view returns (bool) {\n    return configProps._isBurnable;\n  }\n\n  /// @notice Checks if the maximum amount of tokens per address is set\n  /// @return True if there is a maximum limit for token amount per address\n  function isMaxAmountOfTokensSet() public view returns (bool) {\n    return configProps._isMaxAmountOfTokensSet;\n  }\n\n  /// @notice Checks if the maximum amount of token supply is set\n  /// @return True if there is a maximum limit for token supply\n  function isMaxSupplySet() public view returns (bool) {\n    return configProps._isMaxSupplySet;\n  }\n\n  /// @notice Checks if setting a document URI is allowed\n  /// @return True if setting a document URI is allowed\n  function isDocumentUriAllowed() public view returns (bool) {\n    return configProps._isDocumentAllowed;\n  }\n\n  /// @notice Returns the number of decimals used for the token\n  /// @return The number of decimals\n  function decimals() public view virtual override returns (uint8) {\n    return _decimals;\n  }\n\n  /// @notice Checks if the token is taxable\n  /// @return True if the token has tax applied on transfers\n  function isTaxable() public view returns (bool) {\n    return configProps._isTaxable;\n  }\n\n  /// @notice Checks if the token is deflationary\n  /// @return True if the token has deflation applied on transfers\n  function isDeflationary() public view returns (bool) {\n    return configProps._isDeflationary;\n  }\n\n  /// @notice Checks if the token is reflective\n  /// @return True if the token has reflection (ie. holder rewards) applied on transfers\n  function isReflective() public view returns (bool) {\n    return configProps._isReflective;\n  }\n\n  /// @notice Sets a new document URI\n  /// @dev Can only be called by the contract owner\n  /// @param newDocumentUri The new URI to be set\n  function setDocumentUri(string memory newDocumentUri) external onlyOwner {\n    if (!isDocumentUriAllowed()) {\n      revert DocumentUriNotAllowed();\n    }\n    documentUri = newDocumentUri;\n    emit DocumentUriSet(newDocumentUri);\n  }\n\n  /// @notice Sets a new maximum token amount per address\n  /// @dev Can only be called by the contract owner\n  /// @param newMaxTokenAmount The new maximum token amount per address\n  function setMaxTokenAmountPerAddress(\n    uint256 newMaxTokenAmount\n  ) external onlyOwner {\n    if (!isMaxAmountOfTokensSet()) {\n      revert MaxTokenAmountNotAllowed();\n    }\n    if (newMaxTokenAmount <= maxTokenAmountPerAddress) {\n      revert MaxTokenAmountPerAddrLtPrevious();\n    }\n\n    maxTokenAmountPerAddress = newMaxTokenAmount;\n    emit MaxTokenAmountPerSet(newMaxTokenAmount);\n  }\n\n  /// @notice Sets a new reflection fee\n  /// @dev Can only be called by the contract owner\n  /// @param _feeBPS The reflection fee in basis points\n  function setReflectionConfig(uint256 _feeBPS) external onlyOwner {\n    if (!isReflective()) {\n      revert TokenIsNotReflective();\n    }\n    super._setReflectionFee(_feeBPS);\n\n    emit ReflectionConfigSet(_feeBPS);\n  }\n\n  /// @notice Sets a new tax configuration\n  /// @dev Can only be called by the contract owner\n  /// @param _taxAddress The address where tax will be sent\n  /// @param _taxBPS The tax rate in basis points\n  function setTaxConfig(\n    address _taxAddress,\n    uint256 _taxBPS\n  ) external onlyOwner {\n    if (!isTaxable()) {\n      revert TokenIsNotTaxable();\n    }\n\n    uint256 totalBPS = deflationBPS + tFeeBPS + _taxBPS;\n    if (totalBPS > MAX_ALLOWED_BPS) {\n      revert InvalidTotalBPS(totalBPS);\n    }\n    LibCommon.validateAddress(_taxAddress);\n    taxAddress = _taxAddress;\n    taxBPS = _taxBPS;\n    emit TaxConfigSet(_taxAddress, _taxBPS);\n  }\n\n  /// @notice Sets a new deflation configuration\n  /// @dev Can only be called by the contract owner\n  /// @param _deflationBPS The deflation rate in basis points\n  function setDeflationConfig(uint256 _deflationBPS) external onlyOwner {\n    if (!isDeflationary()) {\n      revert TokenIsNotDeflationary();\n    }\n    uint256 totalBPS = deflationBPS + tFeeBPS + _deflationBPS;\n    if (totalBPS > MAX_ALLOWED_BPS) {\n      revert InvalidTotalBPS(totalBPS);\n    }\n    deflationBPS = _deflationBPS;\n    emit DeflationConfigSet(_deflationBPS);\n  }\n\n  /// @notice Transfers tokens to a specified address\n  /// @dev Overrides the ERC20 transfer function with added tax and deflation logic\n  /// @param to The address to transfer tokens to\n  /// @param amount The amount of tokens to be transferred\n  /// @return True if the transfer was successful\n  function transfer(\n    address to,\n    uint256 amount\n  ) public virtual override returns (bool) {\n    uint256 taxAmount = _taxAmount(msg.sender, amount);\n    uint256 deflationAmount = _deflationAmount(amount);\n    uint256 amountToTransfer = amount - taxAmount - deflationAmount;\n\n    if (isMaxAmountOfTokensSet()) {\n      if (balanceOf(to) + amountToTransfer > maxTokenAmountPerAddress) {\n        revert DestBalanceExceedsMaxAllowed(to);\n      }\n    }\n\n    if (taxAmount != 0) {\n      _transferNonReflectedTax(msg.sender, taxAddress, taxAmount);\n    }\n    if (deflationAmount != 0) {\n      _burn(msg.sender, deflationAmount);\n    }\n    return super.transfer(to, amountToTransfer);\n  }\n\n  /// @notice Transfers tokens from one address to another\n  /// @dev Overrides the ERC20 transferFrom function with added tax and deflation logic\n  /// @param from The address which you want to send tokens from\n  /// @param to The address which you want to transfer to\n  /// @param amount The amount of tokens to be transferred\n  /// @return True if the transfer was successful\n  function transferFrom(\n    address from,\n    address to,\n    uint256 amount\n  ) public virtual override returns (bool) {\n    uint256 taxAmount = _taxAmount(from, amount);\n    uint256 deflationAmount = _deflationAmount(amount);\n    uint256 amountToTransfer = amount - taxAmount - deflationAmount;\n\n    if (isMaxAmountOfTokensSet()) {\n      if (balanceOf(to) + amountToTransfer > maxTokenAmountPerAddress) {\n        revert DestBalanceExceedsMaxAllowed(to);\n      }\n    }\n\n    if (taxAmount != 0) {\n      _transferNonReflectedTax(from, taxAddress, taxAmount);\n    }\n    if (deflationAmount != 0) {\n      _burn(from, deflationAmount);\n    }\n\n    return super.transferFrom(from, to, amountToTransfer);\n  }\n\n  /// @notice Mints new tokens to a specified address\n  /// @dev Can only be called by the contract owner and if minting is enabled\n  /// @param to The address to mint tokens to\n  /// @param amount The amount of tokens to mint\n  function mint(address to, uint256 amount) external onlyOwner {\n    if (!isMintable()) {\n      revert MintingNotEnabled();\n    }\n    if (isMaxAmountOfTokensSet()) {\n      if (balanceOf(to) + amount > maxTokenAmountPerAddress) {\n        revert DestBalanceExceedsMaxAllowed(to);\n      }\n    }\n    if (isMaxSupplySet()) {\n      if (totalSupply() + amount > maxTotalSupply) {\n        revert TotalSupplyExceedsMaxAllowedAmount();\n      }\n    }\n\n    super._mint(to, amount);\n  }\n\n  /// @notice Burns a specific amount of tokens\n  /// @dev Can only be called by the contract owner and if burning is enabled\n  /// @param amount The amount of tokens to be burned\n  function burn(uint256 amount) external onlyOwner {\n    if (!isBurnable()) {\n      revert BurningNotEnabled();\n    }\n    _burn(msg.sender, amount);\n  }\n\n  /// @notice Renounces ownership of the contract\n  /// @dev Leaves the contract without an owner, disabling any functions that require the owner's authorization\n  function renounceOwnership() public override onlyOwner {\n    super.renounceOwnership();\n  }\n\n  /// @notice Transfers ownership of the contract to a new account\n  /// @dev Can only be called by the current owner\n  /// @param newOwner The address of the new owner\n  function transferOwnership(address newOwner) public override onlyOwner {\n    super.transferOwnership(newOwner);\n  }\n\n  // Internal Functions\n\n  /// @notice Calculates the tax amount for a transfer\n  /// @param sender The address initiating the transfer\n  /// @param amount The amount of tokens being transferred\n  /// @return taxAmount The calculated tax amount\n  function _taxAmount(\n    address sender,\n    uint256 amount\n  ) internal view returns (uint256 taxAmount) {\n    taxAmount = 0;\n    if (taxBPS != 0 && sender != taxAddress) {\n      taxAmount = (amount * taxBPS) / MAX_BPS_AMOUNT;\n    }\n  }\n\n  /// @notice Calculates the deflation amount for a transfer\n  /// @param amount The amount of tokens being transferred\n  /// @return deflationAmount The calculated deflation amount\n  function _deflationAmount(\n    uint256 amount\n  ) internal view returns (uint256 deflationAmount) {\n    deflationAmount = 0;\n    if (deflationBPS != 0) {\n      deflationAmount = (amount * deflationBPS) / MAX_BPS_AMOUNT;\n    }\n  }\n}\n","keccak256":"0x8b5e8867c3ce6f028c3eac9fbe0c2e939ea20192e6d720bda51ec1ec38626763","license":"GPL-3.0"},"contracts/ReflectiveERC20.sol":{"content":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.17;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { LibCommon } from \"./lib/LibCommon.sol\";\n\n/// @title A ERC20 implementation with extended reflection token functionalities\n/// @notice Implements ERC20 standards with additional token holder reward feature\nabstract contract ReflectiveERC20 is ERC20 {\n  // Constants\n  uint256 private constant BPS_DIVISOR = 10_000;\n\n  mapping(address => uint256) private _rOwned;\n  mapping(address => uint256) private _tOwned;\n\n  uint256 private constant UINT_256_MAX = type(uint256).max;\n  uint256 private _rTotal;\n  uint256 private _tFeeTotal;\n\n  uint256 public tFeeBPS;\n  bool private immutable isReflective;\n\n  // custom errors\n  error TokenIsNotReflective();\n  error TotalReflectionTooSmall();\n  error ZeroTransferError();\n  error MintingNotEnabled();\n  error BurningNotEnabled();\n  error ERC20InsufficientBalance(\n    address recipient,\n    uint256 fromBalance,\n    uint256 balance\n  );\n\n  /// @notice Gets total supply of the erc20 token\n  /// @return Token total supply\n  function _tTotal() public view virtual returns (uint256) {\n    return totalSupply();\n  }\n\n  /// @notice Constructor to initialize the ReflectionErc20 token\n  /// @param name_ Name of the token\n  /// @param symbol_ Symbol of the token\n  /// @param tokenOwner Address of the token owner\n  /// @param totalSupply_ Initial total supply\n  /// @param decimalsToSet Token decimal number\n  /// @param decimalsToSet Token reward (reflection fee BPS value\n  constructor(\n    string memory name_,\n    string memory symbol_,\n    address tokenOwner,\n    uint256 totalSupply_,\n    uint8 decimalsToSet,\n    uint256 tFeeBPS_,\n    bool isReflective_\n  ) ERC20(name_, symbol_) {\n    if (totalSupply_ != 0) {\n      super._mint(tokenOwner, totalSupply_ * 10 ** decimalsToSet);\n      _rTotal = (UINT_256_MAX - (UINT_256_MAX % totalSupply_));\n    }\n\n    _rOwned[tokenOwner] = _rTotal;\n    tFeeBPS = tFeeBPS_;\n    isReflective = isReflective_;\n  }\n\n  // public standard ERC20 functions\n\n  /// @notice Gets balance the erc20 token for specific address\n  /// @param account Account address\n  /// @return Token balance\n  function balanceOf(address account) public view override returns (uint256) {\n    if (isReflective) {\n      return tokenFromReflection(_rOwned[account]);\n    } else {\n      return super.balanceOf(account);\n    }\n  }\n\n  /// @notice Transfers allowed tokens between accounts\n  /// @param from From account\n  /// @param to To account\n  /// @param value Transferred value\n  /// @return Success\n  function transferFrom(\n    address from,\n    address to,\n    uint256 value\n  ) public virtual override returns (bool) {\n    address spender = super._msgSender();\n    _spendAllowance(from, spender, value);\n    _transfer(from, to, value);\n    return true;\n  }\n\n  /// @notice Transfers tokens from owner to an account\n  /// @param to To account\n  /// @param value Transferred value\n  /// @return Success\n  function transfer(\n    address to,\n    uint256 value\n  ) public virtual override returns (bool) {\n    address owner = super._msgSender();\n    _transfer(owner, to, value);\n    return true;\n  }\n\n  // override internal OZ standard ERC20 functions related to transfer\n\n  /// @notice Transfers tokens from owner to an account\n  /// @param to To account\n  /// @param amount Transferred amount\n  function _transfer(\n    address from,\n    address to,\n    uint256 amount\n  ) internal override {\n    if (isReflective) {\n      LibCommon.validateAddress(from);\n      LibCommon.validateAddress(to);\n      if (amount == 0) {\n        revert ZeroTransferError();\n      }\n\n      _transferReflected(from, to, amount);\n    } else {\n      super._transfer(from, to, amount);\n    }\n  }\n\n  // override incompatible internal OZ standard ERC20 functions to disable them in case\n  // reflection mechanism is used, ie. tFeeBPS is non zero\n\n  /// @notice Creates specified amount of tokens, it either uses standard OZ ERC function\n  ///         or in case of reflection logic, it is prohibited\n  /// @param account Account new tokens will be transferred to\n  /// @param value Created tokens value\n  function _mint(address account, uint256 value) internal override {\n    if (isReflective) {\n      revert MintingNotEnabled();\n    } else {\n      super._mint(account, value);\n    }\n  }\n\n  /// @notice Destroys specified amount of tokens, it either uses standard OZ ERC function\n  ///         or in case of reflection logic, it is prohibited\n  /// @param account Account in which tokens will be destroyed\n  /// @param value Destroyed tokens value\n  function _burn(address account, uint256 value) internal override {\n    if (isReflective) {\n      revert BurningNotEnabled();\n    } else {\n      super._burn(account, value);\n    }\n  }\n\n  // public reflection custom functions\n\n  /// @notice Sets a new reflection fee\n  /// @dev Should only be called by the contract owner\n  /// @param _tFeeBPS The reflection fee in basis points\n  function _setReflectionFee(uint256 _tFeeBPS) internal {\n    if (!isReflective) {\n      revert TokenIsNotReflective();\n    }\n\n    tFeeBPS = _tFeeBPS;\n  }\n\n  /// @notice Calculates number of tokens from reflection amount\n  /// @param rAmount Reflection token amount\n  function tokenFromReflection(uint256 rAmount) public view returns (uint256) {\n    if (rAmount > _rTotal) {\n      revert TotalReflectionTooSmall();\n    }\n\n    uint256 currentRate = _getRate();\n    return rAmount / currentRate;\n  }\n\n  // private reflection custom functions\n\n  /// @notice Transfers reflected amount of tokens\n  /// @param sender Account to transfer tokens from\n  /// @param recipient Account to transfer tokens to\n  /// @param tAmount Total token amount\n  function _transferReflected(\n    address sender,\n    address recipient,\n    uint256 tAmount\n  ) private {\n    uint256 tFee = calculateFee(tAmount);\n    uint256 tTransferAmount = tAmount - tFee;\n    (uint256 rAmount, uint256 rFee, uint256 rTransferAmount) = _getRValues(\n      tAmount,\n      tFee,\n      tTransferAmount\n    );\n\n    if (tAmount != 0) {\n      _rUpdate(sender, recipient, rAmount, rTransferAmount);\n\n      _reflectFee(rFee, tFee);\n      emit Transfer(sender, recipient, tAmount);\n    }\n  }\n\n  /// @notice Deducts reflection fee from reflection supply to 'distribute' token holder rewards\n  /// @param rFee Reflection fee\n  /// @param tFee Token fee\n  function _reflectFee(uint256 rFee, uint256 tFee) private {\n    _rTotal = _rTotal - rFee;\n    _tFeeTotal = _tFeeTotal + tFee;\n  }\n\n  /// @notice Calculates the reflection fee from token amount\n  /// @param _amount Amount of tokens to calculate fee from\n  function calculateFee(uint256 _amount) private view returns (uint256) {\n    return (_amount * tFeeBPS) / BPS_DIVISOR;\n  }\n\n  /// @notice Transfers Tax related tokens and do not apply reflection fees\n  /// @param from Account to transfer tokens from\n  /// @param to Account to transfer tokens to\n  /// @param tAmount Total token amount\n  function _transferNonReflectedTax(\n    address from,\n    address to,\n    uint256 tAmount\n  ) internal {\n    if (isReflective) {\n      if (tAmount != 0) {\n        uint256 currentRate = _getRate();\n        uint256 rAmount = tAmount * currentRate;\n\n        _rUpdate(from, to, rAmount, rAmount);\n        emit Transfer(from, to, tAmount);\n      }\n    } else {\n      super._transfer(from, to, tAmount);\n    }\n  }\n\n  /// @notice Get reflective values from token values\n  /// @param tAmount Token amount\n  /// @param tFee Token fee\n  /// @param tTransferAmount Transfer amount\n  function _getRValues(\n    uint256 tAmount,\n    uint256 tFee,\n    uint256 tTransferAmount\n  ) private view returns (uint256, uint256, uint256) {\n    uint256 currentRate = _getRate();\n    uint256 rAmount = tAmount * currentRate;\n    uint256 rFee = tFee * currentRate;\n    uint256 rTransferAmount = tTransferAmount * currentRate;\n\n    return (rAmount, rFee, rTransferAmount);\n  }\n\n  /// @notice Get ratio rate between reflective and token supply\n  /// @return Reflective rate\n  function _getRate() private view returns (uint256) {\n    (uint256 rSupply, uint256 tSupply) = _getCurrentSupply();\n    return rSupply / tSupply;\n  }\n\n  /// @notice Get reflective and token supplies\n  /// @return Reflective and token supplies\n  function _getCurrentSupply() private view returns (uint256, uint256) {\n    return (_rTotal, _tTotal());\n  }\n\n  /// @notice Update reflective balances to reflect amount transfer,\n  ///         with or without a fee applied. If a fee is applied,\n  ///         the amount deducted from the sender will differ\n  ///         from amount added to the recipient\n  /// @param sender Sender address\n  /// @param recipient Recipient address\n  /// @param rSubAmount Amount to be deducted from sender\n  /// @param rTransferAmount Amount to be added to recipient\n  function _rUpdate(\n    address sender,\n    address recipient,\n    uint256 rSubAmount,\n    uint256 rTransferAmount\n  ) private {\n    uint256 fromBalance = _rOwned[sender];\n    if (fromBalance < rSubAmount) {\n      revert ERC20InsufficientBalance(recipient, fromBalance, rSubAmount);\n    }\n    _rOwned[sender] = _rOwned[sender] - rSubAmount;\n    _rOwned[recipient] = _rOwned[recipient] + rTransferAmount;\n  }\n}\n","keccak256":"0x22a919e286fb96030b6d0c102478dfb504d2d59e16f8a62baaeed6464a344fdd","license":"GPL-3.0"},"contracts/lib/LibCommon.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nlibrary LibCommon {\n  /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n  /*                       CUSTOM ERRORS                        */\n  /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n  /// @dev The ETH transfer has failed.\n  error ETHTransferFailed();\n\n  /// @dev The address is the zero address.\n  error ZeroAddress();\n\n  /// @notice raised when an ERC20 transfer fails\n  error TransferFailed();\n\n  /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n  /*                       ETH OPERATIONS                       */\n  /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n  /// @notice Taken from Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)\n  /// @dev Sends `amount` (in wei) ETH to `to`.\n  /// Reverts upon failure.\n  function safeTransferETH(address to, uint256 amount) internal {\n    // solhint-disable-next-line no-inline-assembly\n    assembly {\n      // Transfer the ETH and check if it succeeded or not.\n      if iszero(call(gas(), to, amount, 0, 0, 0, 0)) {\n        // Store the function selector of `ETHTransferFailed()`.\n        // bytes4(keccak256(bytes(\"ETHTransferFailed()\"))) = 0xb12d13eb\n        mstore(0x00, 0xb12d13eb)\n        // Revert with (offset, size).\n        revert(0x1c, 0x04)\n      }\n    }\n  }\n\n  /// @notice Validates that the address is not the zero address using assembly.\n  /// @dev Reverts if the address is the zero address.\n  function validateAddress(address addr) internal pure {\n    // solhint-disable-next-line no-inline-assembly\n    assembly {\n      if iszero(shl(96, addr)) {\n        // Store the function selector of `ZeroAddress()`.\n        // bytes4(keccak256(bytes(\"ZeroAddress()\"))) = 0xd92e233d\n        mstore(0x00, 0xd92e233d)\n        // Revert with (offset, size).\n        revert(0x1c, 0x04)\n      }\n    }\n  }\n\n  /// @notice Helper function to transfer ERC20 tokens without the need for SafeERC20.\n  /// @dev Reverts if the ERC20 transfer fails.\n  /// @param tokenAddress The address of the ERC20 token.\n  /// @param from The address to transfer the tokens from.\n  /// @param to The address to transfer the tokens to.\n  /// @param amount The amount of tokens to transfer.\n  function safeTransferFrom(\n    address tokenAddress,\n    address from,\n    address to,\n    uint256 amount\n  ) internal returns (bool) {\n    // solhint-disable-next-line avoid-low-level-calls\n    (bool success, bytes memory data) = tokenAddress.call(\n      abi.encodeWithSignature(\n        \"transferFrom(address,address,uint256)\",\n        from,\n        to,\n        amount\n      )\n    );\n    if (!success) {\n      if (data.length != 0) {\n        // bubble up error\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n          let returndata_size := mload(data)\n          revert(add(32, data), returndata_size)\n        }\n      } else {\n        revert TransferFailed();\n      }\n    }\n    return true;\n  }\n\n  /// @notice Helper function to transfer ERC20 tokens without the need for SafeERC20.\n  /// @dev Reverts if the ERC20 transfer fails.\n  /// @param tokenAddress The address of the ERC20 token.\n  /// @param to The address to transfer the tokens to.\n  /// @param amount The amount of tokens to transfer.\n  function safeTransfer(\n    address tokenAddress,\n    address to,\n    uint256 amount\n  ) internal returns (bool) {\n    // solhint-disable-next-line avoid-low-level-calls\n    (bool success, bytes memory data) = tokenAddress.call(\n      abi.encodeWithSignature(\"transfer(address,uint256)\", to, amount)\n    );\n    if (!success) {\n      if (data.length != 0) {\n        // bubble up error\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n          let returndata_size := mload(data)\n          revert(add(32, data), returndata_size)\n        }\n      } else {\n        revert TransferFailed();\n      }\n    }\n    return true;\n  }\n}\n","keccak256":"0x55b4e5340734e424b2ce425593e84ebfc01453c507d97f699892001321529d52","license":"MIT"}},"version":1},"storageLayout":{"types":{"t_bool":{"label":"bool","encoding":"inplace","numberOfBytes":"1"},"t_address":{"label":"address","encoding":"inplace","numberOfBytes":"20"},"t_uint256":{"label":"uint256","encoding":"inplace","numberOfBytes":"32"},"t_string_storage":{"label":"string","encoding":"bytes","numberOfBytes":"32"},"t_mapping(t_address,t_uint256)":{"key":"t_address","label":"mapping(address => uint256)","value":"t_uint256","encoding":"mapping","numberOfBytes":"32"},"t_struct(ERC20ConfigProps)883_storage":{"label":"struct DefiV3Token.ERC20ConfigProps","members":[{"slot":"0","type":"t_bool","astId":868,"label":"_isMintable","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"0","type":"t_bool","astId":870,"label":"_isBurnable","offset":1,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"0","type":"t_bool","astId":872,"label":"_isDocumentAllowed","offset":2,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"0","type":"t_bool","astId":874,"label":"_isMaxAmountOfTokensSet","offset":3,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"0","type":"t_bool","astId":876,"label":"_isMaxSupplySet","offset":4,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"0","type":"t_bool","astId":878,"label":"_isTaxable","offset":5,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"0","type":"t_bool","astId":880,"label":"_isDeflationary","offset":6,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"0","type":"t_bool","astId":882,"label":"_isReflective","offset":7,"contract":"contracts/DefiV3Token.sol:DefiV3Token"}],"encoding":"inplace","numberOfBytes":"32"},"t_mapping(t_address,t_mapping(t_address,t_uint256))":{"key":"t_address","label":"mapping(address => mapping(address => uint256))","value":"t_mapping(t_address,t_uint256)","encoding":"mapping","numberOfBytes":"32"}},"storage":[{"slot":"0","type":"t_mapping(t_address,t_uint256)","astId":128,"label":"_balances","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"1","type":"t_mapping(t_address,t_mapping(t_address,t_uint256))","astId":134,"label":"_allowances","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"2","type":"t_uint256","astId":136,"label":"_totalSupply","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"3","type":"t_string_storage","astId":138,"label":"_name","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"4","type":"t_string_storage","astId":140,"label":"_symbol","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"5","type":"t_mapping(t_address,t_uint256)","astId":1833,"label":"_rOwned","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"6","type":"t_mapping(t_address,t_uint256)","astId":1837,"label":"_tOwned","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"7","type":"t_uint256","astId":1846,"label":"_rTotal","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"8","type":"t_uint256","astId":1848,"label":"_tFeeTotal","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"9","type":"t_uint256","astId":1850,"label":"tFeeBPS","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"10","type":"t_address","astId":7,"label":"_owner","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"11","type":"t_string_storage","astId":856,"label":"initialDocumentUri","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"12","type":"t_string_storage","astId":858,"label":"documentUri","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"13","type":"t_uint256","astId":864,"label":"maxTokenAmountPerAddress","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"14","type":"t_uint256","astId":866,"label":"maxTotalSupply","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"15","type":"t_struct(ERC20ConfigProps)883_storage","astId":886,"label":"configProps","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"16","type":"t_address","astId":892,"label":"taxAddress","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"17","type":"t_uint256","astId":894,"label":"taxBPS","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"18","type":"t_uint256","astId":896,"label":"deflationBPS","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"}]},"transientStorageLayout":null,"userdoc":{"kind":"user","notice":"Implements ERC20 standards with additional features like tax and deflation","methods":{"_tTotal()":{"notice":"Gets total supply of the erc20 token"},"decimals()":{"notice":"Returns the number of decimals used for the token"},"constructor":{"notice":"Constructor to initialize the DeFi token"},"isTaxable()":{"notice":"Checks if the token is taxable"},"isBurnable()":{"notice":"Checks if the token is burnable"},"isMintable()":{"notice":"Checks if the token is mintable"},"burn(uint256)":{"notice":"Burns a specific amount of tokens"},"isReflective()":{"notice":"Checks if the token is reflective"},"isDeflationary()":{"notice":"Checks if the token is deflationary"},"isMaxSupplySet()":{"notice":"Checks if the maximum amount of token supply is set"},"balanceOf(address)":{"notice":"Gets balance the erc20 token for specific address"},"renounceOwnership()":{"notice":"Renounces ownership of the contract"},"mint(address,uint256)":{"notice":"Mints new tokens to a specified address"},"isDocumentUriAllowed()":{"notice":"Checks if setting a document URI is allowed"},"setDocumentUri(string)":{"notice":"Sets a new document URI"},"isMaxAmountOfTokensSet()":{"notice":"Checks if the maximum amount of tokens per address is set"},"transfer(address,uint256)":{"notice":"Transfers tokens to a specified address"},"transferOwnership(address)":{"notice":"Transfers ownership of the contract to a new account"},"setDeflationConfig(uint256)":{"notice":"Sets a new deflation configuration"},"setReflectionConfig(uint256)":{"notice":"Sets a new reflection fee"},"tokenFromReflection(uint256)":{"notice":"Calculates number of tokens from reflection amount"},"setTaxConfig(address,uint256)":{"notice":"Sets a new tax configuration"},"setMaxTokenAmountPerAddress(uint256)":{"notice":"Sets a new maximum token amount per address"},"transferFrom(address,address,uint256)":{"notice":"Transfers tokens from one address to another"}},"version":1},"devdoc":{"kind":"dev","title":"A Defi Token implementation with extended functionalities","methods":{"name()":{"details":"Returns the name of the token."},"owner()":{"details":"Returns the address of the current owner."},"symbol()":{"details":"Returns the symbol of the token, usually a shorter version of the name."},"_tTotal()":{"returns":{"_0":"Token total supply"}},"decimals()":{"returns":{"_0":"The number of decimals"}},"constructor":{"params":{"name_":"Name of the token","symbol_":"Symbol of the token","bpsParams":"array of BPS values in this order:           taxBPS = bpsParams[0],           deflationBPS = bpsParams[1],           rewardFeeBPS = bpsParams[2],","tokenOwner":"Address of the initial token owner","_taxAddress":"Address where tax will be sent","amountParams":"array of amounts for amount specific config:           maxTokenAmount = amountParams[0], Maximum token amount per address           maxSupplyAmount = amountParams[1], Maximum token token supply amount","decimalsToSet":"Number of decimals for the token","newDocumentUri":"URI for the document associated with the token","customConfigProps":"Configuration properties for the token","initialSupplyToSet":"Initial supply of tokens"}},"isTaxable()":{"returns":{"_0":"True if the token has tax applied on transfers"}},"isBurnable()":{"returns":{"_0":"True if the token can be burned"}},"isMintable()":{"returns":{"_0":"True if the token can be minted"}},"burn(uint256)":{"params":{"amount":"The amount of tokens to be burned"},"details":"Can only be called by the contract owner and if burning is enabled"},"totalSupply()":{"details":"See {IERC20-totalSupply}."},"isReflective()":{"returns":{"_0":"True if the token has reflection (ie. holder rewards) applied on transfers"}},"isDeflationary()":{"returns":{"_0":"True if the token has deflation applied on transfers"}},"isMaxSupplySet()":{"returns":{"_0":"True if there is a maximum limit for token supply"}},"balanceOf(address)":{"params":{"account":"Account address"},"returns":{"_0":"Token balance"}},"renounceOwnership()":{"details":"Leaves the contract without an owner, disabling any functions that require the owner's authorization"},"mint(address,uint256)":{"params":{"to":"The address to mint tokens to","amount":"The amount of tokens to mint"},"details":"Can only be called by the contract owner and if minting is enabled"},"isDocumentUriAllowed()":{"returns":{"_0":"True if setting a document URI is allowed"}},"setDocumentUri(string)":{"params":{"newDocumentUri":"The new URI to be set"},"details":"Can only be called by the contract owner"},"approve(address,uint256)":{"details":"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address."},"isMaxAmountOfTokensSet()":{"returns":{"_0":"True if there is a maximum limit for token amount per address"}},"transfer(address,uint256)":{"params":{"to":"The address to transfer tokens to","amount":"The amount of tokens to be transferred"},"details":"Overrides the ERC20 transfer function with added tax and deflation logic","returns":{"_0":"True if the transfer was successful"}},"allowance(address,address)":{"details":"See {IERC20-allowance}."},"transferOwnership(address)":{"params":{"newOwner":"The address of the new owner"},"details":"Can only be called by the current owner"},"setDeflationConfig(uint256)":{"params":{"_deflationBPS":"The deflation rate in basis points"},"details":"Can only be called by the contract owner"},"setReflectionConfig(uint256)":{"params":{"_feeBPS":"The reflection fee in basis points"},"details":"Can only be called by the contract owner"},"tokenFromReflection(uint256)":{"params":{"rAmount":"Reflection token amount"}},"setTaxConfig(address,uint256)":{"params":{"_taxBPS":"The tax rate in basis points","_taxAddress":"The address where tax will be sent"},"details":"Can only be called by the contract owner"},"decreaseAllowance(address,uint256)":{"details":"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`."},"increaseAllowance(address,uint256)":{"details":"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address."},"setMaxTokenAmountPerAddress(uint256)":{"params":{"newMaxTokenAmount":"The new maximum token amount per address"},"details":"Can only be called by the contract owner"},"transferFrom(address,address,uint256)":{"params":{"to":"The address which you want to transfer to","from":"The address which you want to send tokens from","amount":"The amount of tokens to be transferred"},"details":"Overrides the ERC20 transferFrom function with added tax and deflation logic","returns":{"_0":"True if the transfer was successful"}}},"version":1},"sourceIds":{"contracts/DefiV3Token.sol":{"id":5},"contracts/lib/LibCommon.sol":{"id":7},"contracts/ReflectiveERC20.sol":{"id":6},"@openzeppelin/contracts/utils/Context.sol":{"id":4},"@openzeppelin/contracts/access/Ownable.sol":{"id":0},"@openzeppelin/contracts/token/ERC20/ERC20.sol":{"id":1},"@openzeppelin/contracts/token/ERC20/IERC20.sol":{"id":2},"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"id":3}},"additionalInput":null,"stdJsonInput":{"sources":{"contracts/DefiV3Token.sol":{"content":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.17;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { LibCommon } from \"./lib/LibCommon.sol\";\nimport { ReflectiveERC20 } from \"./ReflectiveERC20.sol\";\n\n/// @title A Defi Token implementation with extended functionalities\n/// @notice Implements ERC20 standards with additional features like tax and deflation\ncontract DefiV3Token is ReflectiveERC20, Ownable {\n  // Constants\n  uint256 private constant MAX_BPS_AMOUNT = 10_000;\n  uint256 private constant MAX_ALLOWED_BPS = 2_000;\n  string public constant VERSION = \"defi_v_3\";\n\n  // State Variables\n  string public initialDocumentUri;\n  string public documentUri;\n  uint256 public immutable initialSupply;\n  uint256 public immutable initialMaxTokenAmountPerAddress;\n  uint256 public maxTokenAmountPerAddress;\n  uint256 public maxTotalSupply;\n\n  /// @notice Configuration properties for the ERC20 token\n  struct ERC20ConfigProps {\n    bool _isMintable;\n    bool _isBurnable;\n    bool _isDocumentAllowed;\n    bool _isMaxAmountOfTokensSet;\n    bool _isMaxSupplySet;\n    bool _isTaxable;\n    bool _isDeflationary;\n    bool _isReflective;\n  }\n  ERC20ConfigProps private configProps;\n\n  address public immutable initialTokenOwner;\n  uint8 private immutable _decimals;\n  address public taxAddress;\n  uint256 public taxBPS;\n  uint256 public deflationBPS;\n\n  // Events\n  event DocumentUriSet(string newDocUri);\n  event MaxTokenAmountPerSet(uint256 newMaxTokenAmount);\n  event TaxConfigSet(address indexed _taxAddress, uint256 indexed _taxBPS);\n  event DeflationConfigSet(uint256 indexed _deflationBPS);\n  event ReflectionConfigSet(uint256 indexed _feeBPS);\n\n  // Custom Errors\n  error InvalidMaxTokenAmount(uint256 maxTokenAmount);\n  error InvalidDecimals(uint8 decimals);\n  error MaxTokenAmountPerAddrLtPrevious();\n  error DestBalanceExceedsMaxAllowed(address addr);\n  error DocumentUriNotAllowed();\n  error MaxTokenAmountNotAllowed();\n  error TokenIsNotTaxable();\n  error TokenIsNotDeflationary();\n  error InvalidTotalBPS(uint256 bps);\n  error InvalidReflectiveConfig();\n  error InvalidMaxSupplyConfig();\n  error TotalSupplyExceedsMaxAllowedAmount();\n\n  /// @notice Constructor to initialize the DeFi token\n  /// @param name_ Name of the token\n  /// @param symbol_ Symbol of the token\n  /// @param initialSupplyToSet Initial supply of tokens\n  /// @param decimalsToSet Number of decimals for the token\n  /// @param tokenOwner Address of the initial token owner\n  /// @param customConfigProps Configuration properties for the token\n  /// @param newDocumentUri URI for the document associated with the token\n  /// @param _taxAddress Address where tax will be sent\n  /// @param bpsParams array of BPS values in this order:\n  ///           taxBPS = bpsParams[0],\n  ///           deflationBPS = bpsParams[1],\n  ///           rewardFeeBPS = bpsParams[2],\n  /// @param amountParams array of amounts for amount specific config:\n  ///           maxTokenAmount = amountParams[0], Maximum token amount per address\n  ///           maxSupplyAmount = amountParams[1], Maximum token token supply amount\n\n  constructor(\n    string memory name_,\n    string memory symbol_,\n    uint256 initialSupplyToSet,\n    uint8 decimalsToSet,\n    address tokenOwner,\n    ERC20ConfigProps memory customConfigProps,\n    string memory newDocumentUri,\n    address _taxAddress,\n    uint256[3] memory bpsParams,\n    uint256[2] memory amountParams\n  )\n    ReflectiveERC20(\n      name_,\n      symbol_,\n      tokenOwner,\n      initialSupplyToSet,\n      decimalsToSet,\n      initialSupplyToSet != 0 ? bpsParams[2] : 0,\n      customConfigProps._isReflective\n    )\n  {\n    // reflection feature can't be used in combination with burning/minting/deflation\n    // or reflection config is invalid if no reflection BPS amount is provided\n    if (\n      (customConfigProps._isReflective &&\n        (customConfigProps._isBurnable ||\n          customConfigProps._isMintable ||\n          customConfigProps._isDeflationary)) ||\n      (!customConfigProps._isReflective && bpsParams[2] != 0)\n    ) {\n      revert InvalidReflectiveConfig();\n    }\n\n    if (customConfigProps._isMaxAmountOfTokensSet) {\n      if (amountParams[0] == 0) {\n        revert InvalidMaxTokenAmount(amountParams[0]);\n      }\n    }\n    if (decimalsToSet > 18) {\n      revert InvalidDecimals(decimalsToSet);\n    }\n\n    if (\n      customConfigProps._isMaxSupplySet &&\n      (!customConfigProps._isMintable || (totalSupply() > amountParams[1]))\n    ) {\n      revert InvalidMaxSupplyConfig();\n    }\n\n    bpsInitChecks(customConfigProps, bpsParams, _taxAddress);\n\n    LibCommon.validateAddress(tokenOwner);\n\n    taxAddress = _taxAddress;\n\n    taxBPS = bpsParams[0];\n    deflationBPS = bpsParams[1];\n    initialSupply = initialSupplyToSet;\n    initialMaxTokenAmountPerAddress = amountParams[0];\n    initialDocumentUri = newDocumentUri;\n    initialTokenOwner = tokenOwner;\n    _decimals = decimalsToSet;\n    configProps = customConfigProps;\n    documentUri = newDocumentUri;\n    maxTokenAmountPerAddress = amountParams[0];\n    maxTotalSupply = amountParams[1];\n\n    if (tokenOwner != msg.sender) {\n      transferOwnership(tokenOwner);\n    }\n  }\n\n  function bpsInitChecks(\n    ERC20ConfigProps memory customConfigProps,\n    uint256[3] memory bpsParams,\n    address _taxAddress\n  ) private pure {\n    uint256 totalBPS = 0;\n    if (customConfigProps._isTaxable) {\n      LibCommon.validateAddress(_taxAddress);\n\n      totalBPS += bpsParams[0];\n    }\n    if (customConfigProps._isDeflationary) {\n      totalBPS += bpsParams[1];\n    }\n    if (customConfigProps._isReflective) {\n      totalBPS += bpsParams[2];\n    }\n    if (totalBPS > MAX_ALLOWED_BPS) {\n      revert InvalidTotalBPS(totalBPS);\n    }\n  }\n\n  // Public and External Functions\n\n  /// @notice Checks if the token is mintable\n  /// @return True if the token can be minted\n  function isMintable() public view returns (bool) {\n    return configProps._isMintable;\n  }\n\n  /// @notice Checks if the token is burnable\n  /// @return True if the token can be burned\n  function isBurnable() public view returns (bool) {\n    return configProps._isBurnable;\n  }\n\n  /// @notice Checks if the maximum amount of tokens per address is set\n  /// @return True if there is a maximum limit for token amount per address\n  function isMaxAmountOfTokensSet() public view returns (bool) {\n    return configProps._isMaxAmountOfTokensSet;\n  }\n\n  /// @notice Checks if the maximum amount of token supply is set\n  /// @return True if there is a maximum limit for token supply\n  function isMaxSupplySet() public view returns (bool) {\n    return configProps._isMaxSupplySet;\n  }\n\n  /// @notice Checks if setting a document URI is allowed\n  /// @return True if setting a document URI is allowed\n  function isDocumentUriAllowed() public view returns (bool) {\n    return configProps._isDocumentAllowed;\n  }\n\n  /// @notice Returns the number of decimals used for the token\n  /// @return The number of decimals\n  function decimals() public view virtual override returns (uint8) {\n    return _decimals;\n  }\n\n  /// @notice Checks if the token is taxable\n  /// @return True if the token has tax applied on transfers\n  function isTaxable() public view returns (bool) {\n    return configProps._isTaxable;\n  }\n\n  /// @notice Checks if the token is deflationary\n  /// @return True if the token has deflation applied on transfers\n  function isDeflationary() public view returns (bool) {\n    return configProps._isDeflationary;\n  }\n\n  /// @notice Checks if the token is reflective\n  /// @return True if the token has reflection (ie. holder rewards) applied on transfers\n  function isReflective() public view returns (bool) {\n    return configProps._isReflective;\n  }\n\n  /// @notice Sets a new document URI\n  /// @dev Can only be called by the contract owner\n  /// @param newDocumentUri The new URI to be set\n  function setDocumentUri(string memory newDocumentUri) external onlyOwner {\n    if (!isDocumentUriAllowed()) {\n      revert DocumentUriNotAllowed();\n    }\n    documentUri = newDocumentUri;\n    emit DocumentUriSet(newDocumentUri);\n  }\n\n  /// @notice Sets a new maximum token amount per address\n  /// @dev Can only be called by the contract owner\n  /// @param newMaxTokenAmount The new maximum token amount per address\n  function setMaxTokenAmountPerAddress(\n    uint256 newMaxTokenAmount\n  ) external onlyOwner {\n    if (!isMaxAmountOfTokensSet()) {\n      revert MaxTokenAmountNotAllowed();\n    }\n    if (newMaxTokenAmount <= maxTokenAmountPerAddress) {\n      revert MaxTokenAmountPerAddrLtPrevious();\n    }\n\n    maxTokenAmountPerAddress = newMaxTokenAmount;\n    emit MaxTokenAmountPerSet(newMaxTokenAmount);\n  }\n\n  /// @notice Sets a new reflection fee\n  /// @dev Can only be called by the contract owner\n  /// @param _feeBPS The reflection fee in basis points\n  function setReflectionConfig(uint256 _feeBPS) external onlyOwner {\n    if (!isReflective()) {\n      revert TokenIsNotReflective();\n    }\n    super._setReflectionFee(_feeBPS);\n\n    emit ReflectionConfigSet(_feeBPS);\n  }\n\n  /// @notice Sets a new tax configuration\n  /// @dev Can only be called by the contract owner\n  /// @param _taxAddress The address where tax will be sent\n  /// @param _taxBPS The tax rate in basis points\n  function setTaxConfig(\n    address _taxAddress,\n    uint256 _taxBPS\n  ) external onlyOwner {\n    if (!isTaxable()) {\n      revert TokenIsNotTaxable();\n    }\n\n    uint256 totalBPS = deflationBPS + tFeeBPS + _taxBPS;\n    if (totalBPS > MAX_ALLOWED_BPS) {\n      revert InvalidTotalBPS(totalBPS);\n    }\n    LibCommon.validateAddress(_taxAddress);\n    taxAddress = _taxAddress;\n    taxBPS = _taxBPS;\n    emit TaxConfigSet(_taxAddress, _taxBPS);\n  }\n\n  /// @notice Sets a new deflation configuration\n  /// @dev Can only be called by the contract owner\n  /// @param _deflationBPS The deflation rate in basis points\n  function setDeflationConfig(uint256 _deflationBPS) external onlyOwner {\n    if (!isDeflationary()) {\n      revert TokenIsNotDeflationary();\n    }\n    uint256 totalBPS = deflationBPS + tFeeBPS + _deflationBPS;\n    if (totalBPS > MAX_ALLOWED_BPS) {\n      revert InvalidTotalBPS(totalBPS);\n    }\n    deflationBPS = _deflationBPS;\n    emit DeflationConfigSet(_deflationBPS);\n  }\n\n  /// @notice Transfers tokens to a specified address\n  /// @dev Overrides the ERC20 transfer function with added tax and deflation logic\n  /// @param to The address to transfer tokens to\n  /// @param amount The amount of tokens to be transferred\n  /// @return True if the transfer was successful\n  function transfer(\n    address to,\n    uint256 amount\n  ) public virtual override returns (bool) {\n    uint256 taxAmount = _taxAmount(msg.sender, amount);\n    uint256 deflationAmount = _deflationAmount(amount);\n    uint256 amountToTransfer = amount - taxAmount - deflationAmount;\n\n    if (isMaxAmountOfTokensSet()) {\n      if (balanceOf(to) + amountToTransfer > maxTokenAmountPerAddress) {\n        revert DestBalanceExceedsMaxAllowed(to);\n      }\n    }\n\n    if (taxAmount != 0) {\n      _transferNonReflectedTax(msg.sender, taxAddress, taxAmount);\n    }\n    if (deflationAmount != 0) {\n      _burn(msg.sender, deflationAmount);\n    }\n    return super.transfer(to, amountToTransfer);\n  }\n\n  /// @notice Transfers tokens from one address to another\n  /// @dev Overrides the ERC20 transferFrom function with added tax and deflation logic\n  /// @param from The address which you want to send tokens from\n  /// @param to The address which you want to transfer to\n  /// @param amount The amount of tokens to be transferred\n  /// @return True if the transfer was successful\n  function transferFrom(\n    address from,\n    address to,\n    uint256 amount\n  ) public virtual override returns (bool) {\n    uint256 taxAmount = _taxAmount(from, amount);\n    uint256 deflationAmount = _deflationAmount(amount);\n    uint256 amountToTransfer = amount - taxAmount - deflationAmount;\n\n    if (isMaxAmountOfTokensSet()) {\n      if (balanceOf(to) + amountToTransfer > maxTokenAmountPerAddress) {\n        revert DestBalanceExceedsMaxAllowed(to);\n      }\n    }\n\n    if (taxAmount != 0) {\n      _transferNonReflectedTax(from, taxAddress, taxAmount);\n    }\n    if (deflationAmount != 0) {\n      _burn(from, deflationAmount);\n    }\n\n    return super.transferFrom(from, to, amountToTransfer);\n  }\n\n  /// @notice Mints new tokens to a specified address\n  /// @dev Can only be called by the contract owner and if minting is enabled\n  /// @param to The address to mint tokens to\n  /// @param amount The amount of tokens to mint\n  function mint(address to, uint256 amount) external onlyOwner {\n    if (!isMintable()) {\n      revert MintingNotEnabled();\n    }\n    if (isMaxAmountOfTokensSet()) {\n      if (balanceOf(to) + amount > maxTokenAmountPerAddress) {\n        revert DestBalanceExceedsMaxAllowed(to);\n      }\n    }\n    if (isMaxSupplySet()) {\n      if (totalSupply() + amount > maxTotalSupply) {\n        revert TotalSupplyExceedsMaxAllowedAmount();\n      }\n    }\n\n    super._mint(to, amount);\n  }\n\n  /// @notice Burns a specific amount of tokens\n  /// @dev Can only be called by the contract owner and if burning is enabled\n  /// @param amount The amount of tokens to be burned\n  function burn(uint256 amount) external onlyOwner {\n    if (!isBurnable()) {\n      revert BurningNotEnabled();\n    }\n    _burn(msg.sender, amount);\n  }\n\n  /// @notice Renounces ownership of the contract\n  /// @dev Leaves the contract without an owner, disabling any functions that require the owner's authorization\n  function renounceOwnership() public override onlyOwner {\n    super.renounceOwnership();\n  }\n\n  /// @notice Transfers ownership of the contract to a new account\n  /// @dev Can only be called by the current owner\n  /// @param newOwner The address of the new owner\n  function transferOwnership(address newOwner) public override onlyOwner {\n    super.transferOwnership(newOwner);\n  }\n\n  // Internal Functions\n\n  /// @notice Calculates the tax amount for a transfer\n  /// @param sender The address initiating the transfer\n  /// @param amount The amount of tokens being transferred\n  /// @return taxAmount The calculated tax amount\n  function _taxAmount(\n    address sender,\n    uint256 amount\n  ) internal view returns (uint256 taxAmount) {\n    taxAmount = 0;\n    if (taxBPS != 0 && sender != taxAddress) {\n      taxAmount = (amount * taxBPS) / MAX_BPS_AMOUNT;\n    }\n  }\n\n  /// @notice Calculates the deflation amount for a transfer\n  /// @param amount The amount of tokens being transferred\n  /// @return deflationAmount The calculated deflation amount\n  function _deflationAmount(\n    uint256 amount\n  ) internal view returns (uint256 deflationAmount) {\n    deflationAmount = 0;\n    if (deflationBPS != 0) {\n      deflationAmount = (amount * deflationBPS) / MAX_BPS_AMOUNT;\n    }\n  }\n}\n"},"contracts/lib/LibCommon.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nlibrary LibCommon {\n  /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n  /*                       CUSTOM ERRORS                        */\n  /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n  /// @dev The ETH transfer has failed.\n  error ETHTransferFailed();\n\n  /// @dev The address is the zero address.\n  error ZeroAddress();\n\n  /// @notice raised when an ERC20 transfer fails\n  error TransferFailed();\n\n  /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n  /*                       ETH OPERATIONS                       */\n  /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n  /// @notice Taken from Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)\n  /// @dev Sends `amount` (in wei) ETH to `to`.\n  /// Reverts upon failure.\n  function safeTransferETH(address to, uint256 amount) internal {\n    // solhint-disable-next-line no-inline-assembly\n    assembly {\n      // Transfer the ETH and check if it succeeded or not.\n      if iszero(call(gas(), to, amount, 0, 0, 0, 0)) {\n        // Store the function selector of `ETHTransferFailed()`.\n        // bytes4(keccak256(bytes(\"ETHTransferFailed()\"))) = 0xb12d13eb\n        mstore(0x00, 0xb12d13eb)\n        // Revert with (offset, size).\n        revert(0x1c, 0x04)\n      }\n    }\n  }\n\n  /// @notice Validates that the address is not the zero address using assembly.\n  /// @dev Reverts if the address is the zero address.\n  function validateAddress(address addr) internal pure {\n    // solhint-disable-next-line no-inline-assembly\n    assembly {\n      if iszero(shl(96, addr)) {\n        // Store the function selector of `ZeroAddress()`.\n        // bytes4(keccak256(bytes(\"ZeroAddress()\"))) = 0xd92e233d\n        mstore(0x00, 0xd92e233d)\n        // Revert with (offset, size).\n        revert(0x1c, 0x04)\n      }\n    }\n  }\n\n  /// @notice Helper function to transfer ERC20 tokens without the need for SafeERC20.\n  /// @dev Reverts if the ERC20 transfer fails.\n  /// @param tokenAddress The address of the ERC20 token.\n  /// @param from The address to transfer the tokens from.\n  /// @param to The address to transfer the tokens to.\n  /// @param amount The amount of tokens to transfer.\n  function safeTransferFrom(\n    address tokenAddress,\n    address from,\n    address to,\n    uint256 amount\n  ) internal returns (bool) {\n    // solhint-disable-next-line avoid-low-level-calls\n    (bool success, bytes memory data) = tokenAddress.call(\n      abi.encodeWithSignature(\n        \"transferFrom(address,address,uint256)\",\n        from,\n        to,\n        amount\n      )\n    );\n    if (!success) {\n      if (data.length != 0) {\n        // bubble up error\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n          let returndata_size := mload(data)\n          revert(add(32, data), returndata_size)\n        }\n      } else {\n        revert TransferFailed();\n      }\n    }\n    return true;\n  }\n\n  /// @notice Helper function to transfer ERC20 tokens without the need for SafeERC20.\n  /// @dev Reverts if the ERC20 transfer fails.\n  /// @param tokenAddress The address of the ERC20 token.\n  /// @param to The address to transfer the tokens to.\n  /// @param amount The amount of tokens to transfer.\n  function safeTransfer(\n    address tokenAddress,\n    address to,\n    uint256 amount\n  ) internal returns (bool) {\n    // solhint-disable-next-line avoid-low-level-calls\n    (bool success, bytes memory data) = tokenAddress.call(\n      abi.encodeWithSignature(\"transfer(address,uint256)\", to, amount)\n    );\n    if (!success) {\n      if (data.length != 0) {\n        // bubble up error\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n          let returndata_size := mload(data)\n          revert(add(32, data), returndata_size)\n        }\n      } else {\n        revert TransferFailed();\n      }\n    }\n    return true;\n  }\n}\n"},"contracts/ReflectiveERC20.sol":{"content":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.17;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { LibCommon } from \"./lib/LibCommon.sol\";\n\n/// @title A ERC20 implementation with extended reflection token functionalities\n/// @notice Implements ERC20 standards with additional token holder reward feature\nabstract contract ReflectiveERC20 is ERC20 {\n  // Constants\n  uint256 private constant BPS_DIVISOR = 10_000;\n\n  mapping(address => uint256) private _rOwned;\n  mapping(address => uint256) private _tOwned;\n\n  uint256 private constant UINT_256_MAX = type(uint256).max;\n  uint256 private _rTotal;\n  uint256 private _tFeeTotal;\n\n  uint256 public tFeeBPS;\n  bool private immutable isReflective;\n\n  // custom errors\n  error TokenIsNotReflective();\n  error TotalReflectionTooSmall();\n  error ZeroTransferError();\n  error MintingNotEnabled();\n  error BurningNotEnabled();\n  error ERC20InsufficientBalance(\n    address recipient,\n    uint256 fromBalance,\n    uint256 balance\n  );\n\n  /// @notice Gets total supply of the erc20 token\n  /// @return Token total supply\n  function _tTotal() public view virtual returns (uint256) {\n    return totalSupply();\n  }\n\n  /// @notice Constructor to initialize the ReflectionErc20 token\n  /// @param name_ Name of the token\n  /// @param symbol_ Symbol of the token\n  /// @param tokenOwner Address of the token owner\n  /// @param totalSupply_ Initial total supply\n  /// @param decimalsToSet Token decimal number\n  /// @param decimalsToSet Token reward (reflection fee BPS value\n  constructor(\n    string memory name_,\n    string memory symbol_,\n    address tokenOwner,\n    uint256 totalSupply_,\n    uint8 decimalsToSet,\n    uint256 tFeeBPS_,\n    bool isReflective_\n  ) ERC20(name_, symbol_) {\n    if (totalSupply_ != 0) {\n      super._mint(tokenOwner, totalSupply_ * 10 ** decimalsToSet);\n      _rTotal = (UINT_256_MAX - (UINT_256_MAX % totalSupply_));\n    }\n\n    _rOwned[tokenOwner] = _rTotal;\n    tFeeBPS = tFeeBPS_;\n    isReflective = isReflective_;\n  }\n\n  // public standard ERC20 functions\n\n  /// @notice Gets balance the erc20 token for specific address\n  /// @param account Account address\n  /// @return Token balance\n  function balanceOf(address account) public view override returns (uint256) {\n    if (isReflective) {\n      return tokenFromReflection(_rOwned[account]);\n    } else {\n      return super.balanceOf(account);\n    }\n  }\n\n  /// @notice Transfers allowed tokens between accounts\n  /// @param from From account\n  /// @param to To account\n  /// @param value Transferred value\n  /// @return Success\n  function transferFrom(\n    address from,\n    address to,\n    uint256 value\n  ) public virtual override returns (bool) {\n    address spender = super._msgSender();\n    _spendAllowance(from, spender, value);\n    _transfer(from, to, value);\n    return true;\n  }\n\n  /// @notice Transfers tokens from owner to an account\n  /// @param to To account\n  /// @param value Transferred value\n  /// @return Success\n  function transfer(\n    address to,\n    uint256 value\n  ) public virtual override returns (bool) {\n    address owner = super._msgSender();\n    _transfer(owner, to, value);\n    return true;\n  }\n\n  // override internal OZ standard ERC20 functions related to transfer\n\n  /// @notice Transfers tokens from owner to an account\n  /// @param to To account\n  /// @param amount Transferred amount\n  function _transfer(\n    address from,\n    address to,\n    uint256 amount\n  ) internal override {\n    if (isReflective) {\n      LibCommon.validateAddress(from);\n      LibCommon.validateAddress(to);\n      if (amount == 0) {\n        revert ZeroTransferError();\n      }\n\n      _transferReflected(from, to, amount);\n    } else {\n      super._transfer(from, to, amount);\n    }\n  }\n\n  // override incompatible internal OZ standard ERC20 functions to disable them in case\n  // reflection mechanism is used, ie. tFeeBPS is non zero\n\n  /// @notice Creates specified amount of tokens, it either uses standard OZ ERC function\n  ///         or in case of reflection logic, it is prohibited\n  /// @param account Account new tokens will be transferred to\n  /// @param value Created tokens value\n  function _mint(address account, uint256 value) internal override {\n    if (isReflective) {\n      revert MintingNotEnabled();\n    } else {\n      super._mint(account, value);\n    }\n  }\n\n  /// @notice Destroys specified amount of tokens, it either uses standard OZ ERC function\n  ///         or in case of reflection logic, it is prohibited\n  /// @param account Account in which tokens will be destroyed\n  /// @param value Destroyed tokens value\n  function _burn(address account, uint256 value) internal override {\n    if (isReflective) {\n      revert BurningNotEnabled();\n    } else {\n      super._burn(account, value);\n    }\n  }\n\n  // public reflection custom functions\n\n  /// @notice Sets a new reflection fee\n  /// @dev Should only be called by the contract owner\n  /// @param _tFeeBPS The reflection fee in basis points\n  function _setReflectionFee(uint256 _tFeeBPS) internal {\n    if (!isReflective) {\n      revert TokenIsNotReflective();\n    }\n\n    tFeeBPS = _tFeeBPS;\n  }\n\n  /// @notice Calculates number of tokens from reflection amount\n  /// @param rAmount Reflection token amount\n  function tokenFromReflection(uint256 rAmount) public view returns (uint256) {\n    if (rAmount > _rTotal) {\n      revert TotalReflectionTooSmall();\n    }\n\n    uint256 currentRate = _getRate();\n    return rAmount / currentRate;\n  }\n\n  // private reflection custom functions\n\n  /// @notice Transfers reflected amount of tokens\n  /// @param sender Account to transfer tokens from\n  /// @param recipient Account to transfer tokens to\n  /// @param tAmount Total token amount\n  function _transferReflected(\n    address sender,\n    address recipient,\n    uint256 tAmount\n  ) private {\n    uint256 tFee = calculateFee(tAmount);\n    uint256 tTransferAmount = tAmount - tFee;\n    (uint256 rAmount, uint256 rFee, uint256 rTransferAmount) = _getRValues(\n      tAmount,\n      tFee,\n      tTransferAmount\n    );\n\n    if (tAmount != 0) {\n      _rUpdate(sender, recipient, rAmount, rTransferAmount);\n\n      _reflectFee(rFee, tFee);\n      emit Transfer(sender, recipient, tAmount);\n    }\n  }\n\n  /// @notice Deducts reflection fee from reflection supply to 'distribute' token holder rewards\n  /// @param rFee Reflection fee\n  /// @param tFee Token fee\n  function _reflectFee(uint256 rFee, uint256 tFee) private {\n    _rTotal = _rTotal - rFee;\n    _tFeeTotal = _tFeeTotal + tFee;\n  }\n\n  /// @notice Calculates the reflection fee from token amount\n  /// @param _amount Amount of tokens to calculate fee from\n  function calculateFee(uint256 _amount) private view returns (uint256) {\n    return (_amount * tFeeBPS) / BPS_DIVISOR;\n  }\n\n  /// @notice Transfers Tax related tokens and do not apply reflection fees\n  /// @param from Account to transfer tokens from\n  /// @param to Account to transfer tokens to\n  /// @param tAmount Total token amount\n  function _transferNonReflectedTax(\n    address from,\n    address to,\n    uint256 tAmount\n  ) internal {\n    if (isReflective) {\n      if (tAmount != 0) {\n        uint256 currentRate = _getRate();\n        uint256 rAmount = tAmount * currentRate;\n\n        _rUpdate(from, to, rAmount, rAmount);\n        emit Transfer(from, to, tAmount);\n      }\n    } else {\n      super._transfer(from, to, tAmount);\n    }\n  }\n\n  /// @notice Get reflective values from token values\n  /// @param tAmount Token amount\n  /// @param tFee Token fee\n  /// @param tTransferAmount Transfer amount\n  function _getRValues(\n    uint256 tAmount,\n    uint256 tFee,\n    uint256 tTransferAmount\n  ) private view returns (uint256, uint256, uint256) {\n    uint256 currentRate = _getRate();\n    uint256 rAmount = tAmount * currentRate;\n    uint256 rFee = tFee * currentRate;\n    uint256 rTransferAmount = tTransferAmount * currentRate;\n\n    return (rAmount, rFee, rTransferAmount);\n  }\n\n  /// @notice Get ratio rate between reflective and token supply\n  /// @return Reflective rate\n  function _getRate() private view returns (uint256) {\n    (uint256 rSupply, uint256 tSupply) = _getCurrentSupply();\n    return rSupply / tSupply;\n  }\n\n  /// @notice Get reflective and token supplies\n  /// @return Reflective and token supplies\n  function _getCurrentSupply() private view returns (uint256, uint256) {\n    return (_rTotal, _tTotal());\n  }\n\n  /// @notice Update reflective balances to reflect amount transfer,\n  ///         with or without a fee applied. If a fee is applied,\n  ///         the amount deducted from the sender will differ\n  ///         from amount added to the recipient\n  /// @param sender Sender address\n  /// @param recipient Recipient address\n  /// @param rSubAmount Amount to be deducted from sender\n  /// @param rTransferAmount Amount to be added to recipient\n  function _rUpdate(\n    address sender,\n    address recipient,\n    uint256 rSubAmount,\n    uint256 rTransferAmount\n  ) private {\n    uint256 fromBalance = _rOwned[sender];\n    if (fromBalance < rSubAmount) {\n      revert ERC20InsufficientBalance(recipient, fromBalance, rSubAmount);\n    }\n    _rOwned[sender] = _rOwned[sender] - rSubAmount;\n    _rOwned[recipient] = _rOwned[recipient] + rTransferAmount;\n  }\n}\n"},"@openzeppelin/contracts/utils/Context.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"},"@openzeppelin/contracts/access/Ownable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor() {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"},"@openzeppelin/contracts/token/ERC20/ERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n    mapping(address => uint256) private _balances;\n\n    mapping(address => mapping(address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the default value returned by this function, unless\n     * it's overridden.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual override returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address to, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, amount);\n        _transfer(from, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, allowance(owner, spender) + addedValue);\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        uint256 currentAllowance = allowance(owner, spender);\n        require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n        unchecked {\n            _approve(owner, spender, currentAllowance - subtractedValue);\n        }\n\n        return true;\n    }\n\n    /**\n     * @dev Moves `amount` of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     */\n    function _transfer(address from, address to, uint256 amount) internal virtual {\n        require(from != address(0), \"ERC20: transfer from the zero address\");\n        require(to != address(0), \"ERC20: transfer to the zero address\");\n\n        _beforeTokenTransfer(from, to, amount);\n\n        uint256 fromBalance = _balances[from];\n        require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n        unchecked {\n            _balances[from] = fromBalance - amount;\n            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n            // decrementing then incrementing.\n            _balances[to] += amount;\n        }\n\n        emit Transfer(from, to, amount);\n\n        _afterTokenTransfer(from, to, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply += amount;\n        unchecked {\n            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n            _balances[account] += amount;\n        }\n        emit Transfer(address(0), account, amount);\n\n        _afterTokenTransfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        uint256 accountBalance = _balances[account];\n        require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n        unchecked {\n            _balances[account] = accountBalance - amount;\n            // Overflow not possible: amount <= accountBalance <= totalSupply.\n            _totalSupply -= amount;\n        }\n\n        emit Transfer(account, address(0), amount);\n\n        _afterTokenTransfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(address owner, address spender, uint256 amount) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n     *\n     * Does not update the allowance amount in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Might emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n            unchecked {\n                _approve(owner, spender, currentAllowance - amount);\n            }\n        }\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n    /**\n     * @dev Hook that is called after any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * has been transferred to `to`.\n     * - when `from` is zero, `amount` tokens have been minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n"},"@openzeppelin/contracts/token/ERC20/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n"},"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"}},"language":"Solidity","settings":{"metadata":{"bytecodeHash":"ipfs","useLiteralContent":true},"libraries":{},"optimizer":{"runs":1337,"enabled":true},"evmVersion":"london","remappings":[]}},"stdJsonOutput":{"sources":{"contracts/DefiV3Token.sol":{"id":5},"contracts/lib/LibCommon.sol":{"id":7},"contracts/ReflectiveERC20.sol":{"id":6},"@openzeppelin/contracts/utils/Context.sol":{"id":4},"@openzeppelin/contracts/access/Ownable.sol":{"id":0},"@openzeppelin/contracts/token/ERC20/ERC20.sol":{"id":1},"@openzeppelin/contracts/token/ERC20/IERC20.sol":{"id":2},"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"id":3}},"contracts":{"contracts/DefiV3Token.sol":{"DefiV3Token":{"abi":[{"type":"constructor","inputs":[{"name":"name_","type":"string","internalType":"string"},{"name":"symbol_","type":"string","internalType":"string"},{"name":"initialSupplyToSet","type":"uint256","internalType":"uint256"},{"name":"decimalsToSet","type":"uint8","internalType":"uint8"},{"name":"tokenOwner","type":"address","internalType":"address"},{"name":"customConfigProps","type":"tuple","components":[{"name":"_isMintable","type":"bool","internalType":"bool"},{"name":"_isBurnable","type":"bool","internalType":"bool"},{"name":"_isDocumentAllowed","type":"bool","internalType":"bool"},{"name":"_isMaxAmountOfTokensSet","type":"bool","internalType":"bool"},{"name":"_isMaxSupplySet","type":"bool","internalType":"bool"},{"name":"_isTaxable","type":"bool","internalType":"bool"},{"name":"_isDeflationary","type":"bool","internalType":"bool"},{"name":"_isReflective","type":"bool","internalType":"bool"}],"internalType":"struct DefiV3Token.ERC20ConfigProps"},{"name":"newDocumentUri","type":"string","internalType":"string"},{"name":"_taxAddress","type":"address","internalType":"address"},{"name":"bpsParams","type":"uint256[3]","internalType":"uint256[3]"},{"name":"amountParams","type":"uint256[2]","internalType":"uint256[2]"}],"stateMutability":"nonpayable"},{"name":"BurningNotEnabled","type":"error","inputs":[]},{"name":"DestBalanceExceedsMaxAllowed","type":"error","inputs":[{"name":"addr","type":"address","internalType":"address"}]},{"name":"DocumentUriNotAllowed","type":"error","inputs":[]},{"name":"ERC20InsufficientBalance","type":"error","inputs":[{"name":"recipient","type":"address","internalType":"address"},{"name":"fromBalance","type":"uint256","internalType":"uint256"},{"name":"balance","type":"uint256","internalType":"uint256"}]},{"name":"InvalidDecimals","type":"error","inputs":[{"name":"decimals","type":"uint8","internalType":"uint8"}]},{"name":"InvalidMaxSupplyConfig","type":"error","inputs":[]},{"name":"InvalidMaxTokenAmount","type":"error","inputs":[{"name":"maxTokenAmount","type":"uint256","internalType":"uint256"}]},{"name":"InvalidReflectiveConfig","type":"error","inputs":[]},{"name":"InvalidTotalBPS","type":"error","inputs":[{"name":"bps","type":"uint256","internalType":"uint256"}]},{"name":"MaxTokenAmountNotAllowed","type":"error","inputs":[]},{"name":"MaxTokenAmountPerAddrLtPrevious","type":"error","inputs":[]},{"name":"MintingNotEnabled","type":"error","inputs":[]},{"name":"TokenIsNotDeflationary","type":"error","inputs":[]},{"name":"TokenIsNotReflective","type":"error","inputs":[]},{"name":"TokenIsNotTaxable","type":"error","inputs":[]},{"name":"TotalReflectionTooSmall","type":"error","inputs":[]},{"name":"TotalSupplyExceedsMaxAllowedAmount","type":"error","inputs":[]},{"name":"ZeroTransferError","type":"error","inputs":[]},{"name":"Approval","type":"event","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"spender","type":"address","indexed":true,"internalType":"address"},{"name":"value","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"DeflationConfigSet","type":"event","inputs":[{"name":"_deflationBPS","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"DocumentUriSet","type":"event","inputs":[{"name":"newDocUri","type":"string","indexed":false,"internalType":"string"}],"anonymous":false},{"name":"MaxTokenAmountPerSet","type":"event","inputs":[{"name":"newMaxTokenAmount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"OwnershipTransferred","type":"event","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"ReflectionConfigSet","type":"event","inputs":[{"name":"_feeBPS","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"TaxConfigSet","type":"event","inputs":[{"name":"_taxAddress","type":"address","indexed":true,"internalType":"address"},{"name":"_taxBPS","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"Transfer","type":"event","inputs":[{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"value","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"VERSION","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"_tTotal","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"allowance","type":"function","inputs":[{"name":"owner","type":"address","internalType":"address"},{"name":"spender","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"approve","type":"function","inputs":[{"name":"spender","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"name":"balanceOf","type":"function","inputs":[{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"burn","type":"function","inputs":[{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"decimals","type":"function","inputs":[],"outputs":[{"name":"","type":"uint8","internalType":"uint8"}],"stateMutability":"view"},{"name":"decreaseAllowance","type":"function","inputs":[{"name":"spender","type":"address","internalType":"address"},{"name":"subtractedValue","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"name":"deflationBPS","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"documentUri","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"increaseAllowance","type":"function","inputs":[{"name":"spender","type":"address","internalType":"address"},{"name":"addedValue","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"name":"initialDocumentUri","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"initialMaxTokenAmountPerAddress","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"initialSupply","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"initialTokenOwner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"isBurnable","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"isDeflationary","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"isDocumentUriAllowed","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"isMaxAmountOfTokensSet","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"isMaxSupplySet","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"isMintable","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"isReflective","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"isTaxable","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"maxTokenAmountPerAddress","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"maxTotalSupply","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"mint","type":"function","inputs":[{"name":"to","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"name","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"owner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"renounceOwnership","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"setDeflationConfig","type":"function","inputs":[{"name":"_deflationBPS","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setDocumentUri","type":"function","inputs":[{"name":"newDocumentUri","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setMaxTokenAmountPerAddress","type":"function","inputs":[{"name":"newMaxTokenAmount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setReflectionConfig","type":"function","inputs":[{"name":"_feeBPS","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setTaxConfig","type":"function","inputs":[{"name":"_taxAddress","type":"address","internalType":"address"},{"name":"_taxBPS","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"symbol","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"tFeeBPS","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"taxAddress","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"taxBPS","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"tokenFromReflection","type":"function","inputs":[{"name":"rAmount","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"totalSupply","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"transfer","type":"function","inputs":[{"name":"to","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"name":"transferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"name":"transferOwnership","type":"function","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"}],"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"initialSupplyToSet\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"decimalsToSet\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"tokenOwner\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"_isMintable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_isBurnable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_isDocumentAllowed\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_isMaxAmountOfTokensSet\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_isMaxSupplySet\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_isTaxable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_isDeflationary\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_isReflective\",\"type\":\"bool\"}],\"internalType\":\"struct DefiV3Token.ERC20ConfigProps\",\"name\":\"customConfigProps\",\"type\":\"tuple\"},{\"internalType\":\"string\",\"name\":\"newDocumentUri\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_taxAddress\",\"type\":\"address\"},{\"internalType\":\"uint256[3]\",\"name\":\"bpsParams\",\"type\":\"uint256[3]\"},{\"internalType\":\"uint256[2]\",\"name\":\"amountParams\",\"type\":\"uint256[2]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BurningNotEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"DestBalanceExceedsMaxAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DocumentUriNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fromBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"name\":\"InvalidDecimals\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMaxSupplyConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxTokenAmount\",\"type\":\"uint256\"}],\"name\":\"InvalidMaxTokenAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReflectiveConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"bps\",\"type\":\"uint256\"}],\"name\":\"InvalidTotalBPS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxTokenAmountNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxTokenAmountPerAddrLtPrevious\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MintingNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenIsNotDeflationary\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenIsNotReflective\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenIsNotTaxable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TotalReflectionTooSmall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TotalSupplyExceedsMaxAllowedAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroTransferError\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_deflationBPS\",\"type\":\"uint256\"}],\"name\":\"DeflationConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"newDocUri\",\"type\":\"string\"}],\"name\":\"DocumentUriSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newMaxTokenAmount\",\"type\":\"uint256\"}],\"name\":\"MaxTokenAmountPerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_feeBPS\",\"type\":\"uint256\"}],\"name\":\"ReflectionConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_taxAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_taxBPS\",\"type\":\"uint256\"}],\"name\":\"TaxConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"_tTotal\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"deflationBPS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"documentUri\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialDocumentUri\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialMaxTokenAmountPerAddress\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialTokenOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isBurnable\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isDeflationary\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isDocumentUriAllowed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isMaxAmountOfTokensSet\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isMaxSupplySet\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isMintable\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isReflective\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isTaxable\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxTokenAmountPerAddress\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxTotalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_deflationBPS\",\"type\":\"uint256\"}],\"name\":\"setDeflationConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"newDocumentUri\",\"type\":\"string\"}],\"name\":\"setDocumentUri\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newMaxTokenAmount\",\"type\":\"uint256\"}],\"name\":\"setMaxTokenAmountPerAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_feeBPS\",\"type\":\"uint256\"}],\"name\":\"setReflectionConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_taxAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_taxBPS\",\"type\":\"uint256\"}],\"name\":\"setTaxConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tFeeBPS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"taxAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"taxBPS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"rAmount\",\"type\":\"uint256\"}],\"name\":\"tokenFromReflection\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"_tTotal()\":{\"returns\":{\"_0\":\"Token total supply\"}},\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"params\":{\"account\":\"Account address\"},\"returns\":{\"_0\":\"Token balance\"}},\"burn(uint256)\":{\"details\":\"Can only be called by the contract owner and if burning is enabled\",\"params\":{\"amount\":\"The amount of tokens to be burned\"}},\"constructor\":{\"params\":{\"_taxAddress\":\"Address where tax will be sent\",\"amountParams\":\"array of amounts for amount specific config:           maxTokenAmount = amountParams[0], Maximum token amount per address           maxSupplyAmount = amountParams[1], Maximum token token supply amount\",\"bpsParams\":\"array of BPS values in this order:           taxBPS = bpsParams[0],           deflationBPS = bpsParams[1],           rewardFeeBPS = bpsParams[2],\",\"customConfigProps\":\"Configuration properties for the token\",\"decimalsToSet\":\"Number of decimals for the token\",\"initialSupplyToSet\":\"Initial supply of tokens\",\"name_\":\"Name of the token\",\"newDocumentUri\":\"URI for the document associated with the token\",\"symbol_\":\"Symbol of the token\",\"tokenOwner\":\"Address of the initial token owner\"}},\"decimals()\":{\"returns\":{\"_0\":\"The number of decimals\"}},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"isBurnable()\":{\"returns\":{\"_0\":\"True if the token can be burned\"}},\"isDeflationary()\":{\"returns\":{\"_0\":\"True if the token has deflation applied on transfers\"}},\"isDocumentUriAllowed()\":{\"returns\":{\"_0\":\"True if setting a document URI is allowed\"}},\"isMaxAmountOfTokensSet()\":{\"returns\":{\"_0\":\"True if there is a maximum limit for token amount per address\"}},\"isMaxSupplySet()\":{\"returns\":{\"_0\":\"True if there is a maximum limit for token supply\"}},\"isMintable()\":{\"returns\":{\"_0\":\"True if the token can be minted\"}},\"isReflective()\":{\"returns\":{\"_0\":\"True if the token has reflection (ie. holder rewards) applied on transfers\"}},\"isTaxable()\":{\"returns\":{\"_0\":\"True if the token has tax applied on transfers\"}},\"mint(address,uint256)\":{\"details\":\"Can only be called by the contract owner and if minting is enabled\",\"params\":{\"amount\":\"The amount of tokens to mint\",\"to\":\"The address to mint tokens to\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without an owner, disabling any functions that require the owner's authorization\"},\"setDeflationConfig(uint256)\":{\"details\":\"Can only be called by the contract owner\",\"params\":{\"_deflationBPS\":\"The deflation rate in basis points\"}},\"setDocumentUri(string)\":{\"details\":\"Can only be called by the contract owner\",\"params\":{\"newDocumentUri\":\"The new URI to be set\"}},\"setMaxTokenAmountPerAddress(uint256)\":{\"details\":\"Can only be called by the contract owner\",\"params\":{\"newMaxTokenAmount\":\"The new maximum token amount per address\"}},\"setReflectionConfig(uint256)\":{\"details\":\"Can only be called by the contract owner\",\"params\":{\"_feeBPS\":\"The reflection fee in basis points\"}},\"setTaxConfig(address,uint256)\":{\"details\":\"Can only be called by the contract owner\",\"params\":{\"_taxAddress\":\"The address where tax will be sent\",\"_taxBPS\":\"The tax rate in basis points\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"tokenFromReflection(uint256)\":{\"params\":{\"rAmount\":\"Reflection token amount\"}},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"Overrides the ERC20 transfer function with added tax and deflation logic\",\"params\":{\"amount\":\"The amount of tokens to be transferred\",\"to\":\"The address to transfer tokens to\"},\"returns\":{\"_0\":\"True if the transfer was successful\"}},\"transferFrom(address,address,uint256)\":{\"details\":\"Overrides the ERC20 transferFrom function with added tax and deflation logic\",\"params\":{\"amount\":\"The amount of tokens to be transferred\",\"from\":\"The address which you want to send tokens from\",\"to\":\"The address which you want to transfer to\"},\"returns\":{\"_0\":\"True if the transfer was successful\"}},\"transferOwnership(address)\":{\"details\":\"Can only be called by the current owner\",\"params\":{\"newOwner\":\"The address of the new owner\"}}},\"title\":\"A Defi Token implementation with extended functionalities\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"_tTotal()\":{\"notice\":\"Gets total supply of the erc20 token\"},\"balanceOf(address)\":{\"notice\":\"Gets balance the erc20 token for specific address\"},\"burn(uint256)\":{\"notice\":\"Burns a specific amount of tokens\"},\"constructor\":{\"notice\":\"Constructor to initialize the DeFi token\"},\"decimals()\":{\"notice\":\"Returns the number of decimals used for the token\"},\"isBurnable()\":{\"notice\":\"Checks if the token is burnable\"},\"isDeflationary()\":{\"notice\":\"Checks if the token is deflationary\"},\"isDocumentUriAllowed()\":{\"notice\":\"Checks if setting a document URI is allowed\"},\"isMaxAmountOfTokensSet()\":{\"notice\":\"Checks if the maximum amount of tokens per address is set\"},\"isMaxSupplySet()\":{\"notice\":\"Checks if the maximum amount of token supply is set\"},\"isMintable()\":{\"notice\":\"Checks if the token is mintable\"},\"isReflective()\":{\"notice\":\"Checks if the token is reflective\"},\"isTaxable()\":{\"notice\":\"Checks if the token is taxable\"},\"mint(address,uint256)\":{\"notice\":\"Mints new tokens to a specified address\"},\"renounceOwnership()\":{\"notice\":\"Renounces ownership of the contract\"},\"setDeflationConfig(uint256)\":{\"notice\":\"Sets a new deflation configuration\"},\"setDocumentUri(string)\":{\"notice\":\"Sets a new document URI\"},\"setMaxTokenAmountPerAddress(uint256)\":{\"notice\":\"Sets a new maximum token amount per address\"},\"setReflectionConfig(uint256)\":{\"notice\":\"Sets a new reflection fee\"},\"setTaxConfig(address,uint256)\":{\"notice\":\"Sets a new tax configuration\"},\"tokenFromReflection(uint256)\":{\"notice\":\"Calculates number of tokens from reflection amount\"},\"transfer(address,uint256)\":{\"notice\":\"Transfers tokens to a specified address\"},\"transferFrom(address,address,uint256)\":{\"notice\":\"Transfers tokens from one address to another\"},\"transferOwnership(address)\":{\"notice\":\"Transfers ownership of the contract to a new account\"}},\"notice\":\"Implements ERC20 standards with additional features like tax and deflation\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DefiV3Token.sol\":\"DefiV3Token\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1337},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n    address private _owner;\\n\\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n    /**\\n     * @dev Initializes the contract setting the deployer as the initial owner.\\n     */\\n    constructor() {\\n        _transferOwnership(_msgSender());\\n    }\\n\\n    /**\\n     * @dev Throws if called by any account other than the owner.\\n     */\\n    modifier onlyOwner() {\\n        _checkOwner();\\n        _;\\n    }\\n\\n    /**\\n     * @dev Returns the address of the current owner.\\n     */\\n    function owner() public view virtual returns (address) {\\n        return _owner;\\n    }\\n\\n    /**\\n     * @dev Throws if the sender is not the owner.\\n     */\\n    function _checkOwner() internal view virtual {\\n        require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n    }\\n\\n    /**\\n     * @dev Leaves the contract without owner. It will not be possible to call\\n     * `onlyOwner` functions. Can only be called by the current owner.\\n     *\\n     * NOTE: Renouncing ownership will leave the contract without an owner,\\n     * thereby disabling any functionality that is only available to the owner.\\n     */\\n    function renounceOwnership() public virtual onlyOwner {\\n        _transferOwnership(address(0));\\n    }\\n\\n    /**\\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n     * Can only be called by the current owner.\\n     */\\n    function transferOwnership(address newOwner) public virtual onlyOwner {\\n        require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n        _transferOwnership(newOwner);\\n    }\\n\\n    /**\\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n     * Internal function without access restriction.\\n     */\\n    function _transferOwnership(address newOwner) internal virtual {\\n        address oldOwner = _owner;\\n        _owner = newOwner;\\n        emit OwnershipTransferred(oldOwner, newOwner);\\n    }\\n}\\n\",\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"./extensions/IERC20Metadata.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * The default value of {decimals} is 18. To change this, you should override\\n * this function so it returns a different value.\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20, IERC20Metadata {\\n    mapping(address => uint256) private _balances;\\n\\n    mapping(address => mapping(address => uint256)) private _allowances;\\n\\n    uint256 private _totalSupply;\\n\\n    string private _name;\\n    string private _symbol;\\n\\n    /**\\n     * @dev Sets the values for {name} and {symbol}.\\n     *\\n     * All two of these values are immutable: they can only be set once during\\n     * construction.\\n     */\\n    constructor(string memory name_, string memory symbol_) {\\n        _name = name_;\\n        _symbol = symbol_;\\n    }\\n\\n    /**\\n     * @dev Returns the name of the token.\\n     */\\n    function name() public view virtual override returns (string memory) {\\n        return _name;\\n    }\\n\\n    /**\\n     * @dev Returns the symbol of the token, usually a shorter version of the\\n     * name.\\n     */\\n    function symbol() public view virtual override returns (string memory) {\\n        return _symbol;\\n    }\\n\\n    /**\\n     * @dev Returns the number of decimals used to get its user representation.\\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n     *\\n     * Tokens usually opt for a value of 18, imitating the relationship between\\n     * Ether and Wei. This is the default value returned by this function, unless\\n     * it's overridden.\\n     *\\n     * NOTE: This information is only used for _display_ purposes: it in\\n     * no way affects any of the arithmetic of the contract, including\\n     * {IERC20-balanceOf} and {IERC20-transfer}.\\n     */\\n    function decimals() public view virtual override returns (uint8) {\\n        return 18;\\n    }\\n\\n    /**\\n     * @dev See {IERC20-totalSupply}.\\n     */\\n    function totalSupply() public view virtual override returns (uint256) {\\n        return _totalSupply;\\n    }\\n\\n    /**\\n     * @dev See {IERC20-balanceOf}.\\n     */\\n    function balanceOf(address account) public view virtual override returns (uint256) {\\n        return _balances[account];\\n    }\\n\\n    /**\\n     * @dev See {IERC20-transfer}.\\n     *\\n     * Requirements:\\n     *\\n     * - `to` cannot be the zero address.\\n     * - the caller must have a balance of at least `amount`.\\n     */\\n    function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n        address owner = _msgSender();\\n        _transfer(owner, to, amount);\\n        return true;\\n    }\\n\\n    /**\\n     * @dev See {IERC20-allowance}.\\n     */\\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n        return _allowances[owner][spender];\\n    }\\n\\n    /**\\n     * @dev See {IERC20-approve}.\\n     *\\n     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\\n     *\\n     * Requirements:\\n     *\\n     * - `spender` cannot be the zero address.\\n     */\\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n        address owner = _msgSender();\\n        _approve(owner, spender, amount);\\n        return true;\\n    }\\n\\n    /**\\n     * @dev See {IERC20-transferFrom}.\\n     *\\n     * Emits an {Approval} event indicating the updated allowance. This is not\\n     * required by the EIP. See the note at the beginning of {ERC20}.\\n     *\\n     * NOTE: Does not update the allowance if the current allowance\\n     * is the maximum `uint256`.\\n     *\\n     * Requirements:\\n     *\\n     * - `from` and `to` cannot be the zero address.\\n     * - `from` must have a balance of at least `amount`.\\n     * - the caller must have allowance for ``from``'s tokens of at least\\n     * `amount`.\\n     */\\n    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\\n        address spender = _msgSender();\\n        _spendAllowance(from, spender, amount);\\n        _transfer(from, to, amount);\\n        return true;\\n    }\\n\\n    /**\\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\\n     *\\n     * This is an alternative to {approve} that can be used as a mitigation for\\n     * problems described in {IERC20-approve}.\\n     *\\n     * Emits an {Approval} event indicating the updated allowance.\\n     *\\n     * Requirements:\\n     *\\n     * - `spender` cannot be the zero address.\\n     */\\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n        address owner = _msgSender();\\n        _approve(owner, spender, allowance(owner, spender) + addedValue);\\n        return true;\\n    }\\n\\n    /**\\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n     *\\n     * This is an alternative to {approve} that can be used as a mitigation for\\n     * problems described in {IERC20-approve}.\\n     *\\n     * Emits an {Approval} event indicating the updated allowance.\\n     *\\n     * Requirements:\\n     *\\n     * - `spender` cannot be the zero address.\\n     * - `spender` must have allowance for the caller of at least\\n     * `subtractedValue`.\\n     */\\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n        address owner = _msgSender();\\n        uint256 currentAllowance = allowance(owner, spender);\\n        require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n        unchecked {\\n            _approve(owner, spender, currentAllowance - subtractedValue);\\n        }\\n\\n        return true;\\n    }\\n\\n    /**\\n     * @dev Moves `amount` of tokens from `from` to `to`.\\n     *\\n     * This internal function is equivalent to {transfer}, and can be used to\\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\\n     *\\n     * Emits a {Transfer} event.\\n     *\\n     * Requirements:\\n     *\\n     * - `from` cannot be the zero address.\\n     * - `to` cannot be the zero address.\\n     * - `from` must have a balance of at least `amount`.\\n     */\\n    function _transfer(address from, address to, uint256 amount) internal virtual {\\n        require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n        require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n        _beforeTokenTransfer(from, to, amount);\\n\\n        uint256 fromBalance = _balances[from];\\n        require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n        unchecked {\\n            _balances[from] = fromBalance - amount;\\n            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\\n            // decrementing then incrementing.\\n            _balances[to] += amount;\\n        }\\n\\n        emit Transfer(from, to, amount);\\n\\n        _afterTokenTransfer(from, to, amount);\\n    }\\n\\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n     * the total supply.\\n     *\\n     * Emits a {Transfer} event with `from` set to the zero address.\\n     *\\n     * Requirements:\\n     *\\n     * - `account` cannot be the zero address.\\n     */\\n    function _mint(address account, uint256 amount) internal virtual {\\n        require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n        _beforeTokenTransfer(address(0), account, amount);\\n\\n        _totalSupply += amount;\\n        unchecked {\\n            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\\n            _balances[account] += amount;\\n        }\\n        emit Transfer(address(0), account, amount);\\n\\n        _afterTokenTransfer(address(0), account, amount);\\n    }\\n\\n    /**\\n     * @dev Destroys `amount` tokens from `account`, reducing the\\n     * total supply.\\n     *\\n     * Emits a {Transfer} event with `to` set to the zero address.\\n     *\\n     * Requirements:\\n     *\\n     * - `account` cannot be the zero address.\\n     * - `account` must have at least `amount` tokens.\\n     */\\n    function _burn(address account, uint256 amount) internal virtual {\\n        require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n        _beforeTokenTransfer(account, address(0), amount);\\n\\n        uint256 accountBalance = _balances[account];\\n        require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n        unchecked {\\n            _balances[account] = accountBalance - amount;\\n            // Overflow not possible: amount <= accountBalance <= totalSupply.\\n            _totalSupply -= amount;\\n        }\\n\\n        emit Transfer(account, address(0), amount);\\n\\n        _afterTokenTransfer(account, address(0), amount);\\n    }\\n\\n    /**\\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n     *\\n     * This internal function is equivalent to `approve`, and can be used to\\n     * e.g. set automatic allowances for certain subsystems, etc.\\n     *\\n     * Emits an {Approval} event.\\n     *\\n     * Requirements:\\n     *\\n     * - `owner` cannot be the zero address.\\n     * - `spender` cannot be the zero address.\\n     */\\n    function _approve(address owner, address spender, uint256 amount) internal virtual {\\n        require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n        require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n        _allowances[owner][spender] = amount;\\n        emit Approval(owner, spender, amount);\\n    }\\n\\n    /**\\n     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n     *\\n     * Does not update the allowance amount in case of infinite allowance.\\n     * Revert if not enough allowance is available.\\n     *\\n     * Might emit an {Approval} event.\\n     */\\n    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\\n        uint256 currentAllowance = allowance(owner, spender);\\n        if (currentAllowance != type(uint256).max) {\\n            require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n            unchecked {\\n                _approve(owner, spender, currentAllowance - amount);\\n            }\\n        }\\n    }\\n\\n    /**\\n     * @dev Hook that is called before any transfer of tokens. This includes\\n     * minting and burning.\\n     *\\n     * Calling conditions:\\n     *\\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n     * will be transferred to `to`.\\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n     * - `from` and `to` are never both zero.\\n     *\\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n     */\\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\\n\\n    /**\\n     * @dev Hook that is called after any transfer of tokens. This includes\\n     * minting and burning.\\n     *\\n     * Calling conditions:\\n     *\\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n     * has been transferred to `to`.\\n     * - when `from` is zero, `amount` tokens have been minted for `to`.\\n     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n     * - `from` and `to` are never both zero.\\n     *\\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n     */\\n    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\\n}\\n\",\"keccak256\":\"0xa56ca923f70c1748830700250b19c61b70db9a683516dc5e216694a50445d99c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n    /**\\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n     * another (`to`).\\n     *\\n     * Note that `value` may be zero.\\n     */\\n    event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n    /**\\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n     * a call to {approve}. `value` is the new allowance.\\n     */\\n    event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n    /**\\n     * @dev Returns the amount of tokens in existence.\\n     */\\n    function totalSupply() external view returns (uint256);\\n\\n    /**\\n     * @dev Returns the amount of tokens owned by `account`.\\n     */\\n    function balanceOf(address account) external view returns (uint256);\\n\\n    /**\\n     * @dev Moves `amount` tokens from the caller's account to `to`.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transfer(address to, uint256 amount) external returns (bool);\\n\\n    /**\\n     * @dev Returns the remaining number of tokens that `spender` will be\\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n     * zero by default.\\n     *\\n     * This value changes when {approve} or {transferFrom} are called.\\n     */\\n    function allowance(address owner, address spender) external view returns (uint256);\\n\\n    /**\\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n     * that someone may use both the old and the new allowance by unfortunate\\n     * transaction ordering. One possible solution to mitigate this race\\n     * condition is to first reduce the spender's allowance to 0 and set the\\n     * desired value afterwards:\\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n     *\\n     * Emits an {Approval} event.\\n     */\\n    function approve(address spender, uint256 amount) external returns (bool);\\n\\n    /**\\n     * @dev Moves `amount` tokens from `from` to `to` using the\\n     * allowance mechanism. `amount` is then deducted from the caller's\\n     * allowance.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transferFrom(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n    /**\\n     * @dev Returns the name of the token.\\n     */\\n    function name() external view returns (string memory);\\n\\n    /**\\n     * @dev Returns the symbol of the token.\\n     */\\n    function symbol() external view returns (string memory);\\n\\n    /**\\n     * @dev Returns the decimals places of the token.\\n     */\\n    function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n    function _msgSender() internal view virtual returns (address) {\\n        return msg.sender;\\n    }\\n\\n    function _msgData() internal view virtual returns (bytes calldata) {\\n        return msg.data;\\n    }\\n\\n    function _contextSuffixLength() internal view virtual returns (uint256) {\\n        return 0;\\n    }\\n}\\n\",\"keccak256\":\"0xa92e4fa126feb6907daa0513ddd816b2eb91f30a808de54f63c17d0e162c3439\",\"license\":\"MIT\"},\"contracts/DefiV3Token.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { LibCommon } from \\\"./lib/LibCommon.sol\\\";\\nimport { ReflectiveERC20 } from \\\"./ReflectiveERC20.sol\\\";\\n\\n/// @title A Defi Token implementation with extended functionalities\\n/// @notice Implements ERC20 standards with additional features like tax and deflation\\ncontract DefiV3Token is ReflectiveERC20, Ownable {\\n  // Constants\\n  uint256 private constant MAX_BPS_AMOUNT = 10_000;\\n  uint256 private constant MAX_ALLOWED_BPS = 2_000;\\n  string public constant VERSION = \\\"defi_v_3\\\";\\n\\n  // State Variables\\n  string public initialDocumentUri;\\n  string public documentUri;\\n  uint256 public immutable initialSupply;\\n  uint256 public immutable initialMaxTokenAmountPerAddress;\\n  uint256 public maxTokenAmountPerAddress;\\n  uint256 public maxTotalSupply;\\n\\n  /// @notice Configuration properties for the ERC20 token\\n  struct ERC20ConfigProps {\\n    bool _isMintable;\\n    bool _isBurnable;\\n    bool _isDocumentAllowed;\\n    bool _isMaxAmountOfTokensSet;\\n    bool _isMaxSupplySet;\\n    bool _isTaxable;\\n    bool _isDeflationary;\\n    bool _isReflective;\\n  }\\n  ERC20ConfigProps private configProps;\\n\\n  address public immutable initialTokenOwner;\\n  uint8 private immutable _decimals;\\n  address public taxAddress;\\n  uint256 public taxBPS;\\n  uint256 public deflationBPS;\\n\\n  // Events\\n  event DocumentUriSet(string newDocUri);\\n  event MaxTokenAmountPerSet(uint256 newMaxTokenAmount);\\n  event TaxConfigSet(address indexed _taxAddress, uint256 indexed _taxBPS);\\n  event DeflationConfigSet(uint256 indexed _deflationBPS);\\n  event ReflectionConfigSet(uint256 indexed _feeBPS);\\n\\n  // Custom Errors\\n  error InvalidMaxTokenAmount(uint256 maxTokenAmount);\\n  error InvalidDecimals(uint8 decimals);\\n  error MaxTokenAmountPerAddrLtPrevious();\\n  error DestBalanceExceedsMaxAllowed(address addr);\\n  error DocumentUriNotAllowed();\\n  error MaxTokenAmountNotAllowed();\\n  error TokenIsNotTaxable();\\n  error TokenIsNotDeflationary();\\n  error InvalidTotalBPS(uint256 bps);\\n  error InvalidReflectiveConfig();\\n  error InvalidMaxSupplyConfig();\\n  error TotalSupplyExceedsMaxAllowedAmount();\\n\\n  /// @notice Constructor to initialize the DeFi token\\n  /// @param name_ Name of the token\\n  /// @param symbol_ Symbol of the token\\n  /// @param initialSupplyToSet Initial supply of tokens\\n  /// @param decimalsToSet Number of decimals for the token\\n  /// @param tokenOwner Address of the initial token owner\\n  /// @param customConfigProps Configuration properties for the token\\n  /// @param newDocumentUri URI for the document associated with the token\\n  /// @param _taxAddress Address where tax will be sent\\n  /// @param bpsParams array of BPS values in this order:\\n  ///           taxBPS = bpsParams[0],\\n  ///           deflationBPS = bpsParams[1],\\n  ///           rewardFeeBPS = bpsParams[2],\\n  /// @param amountParams array of amounts for amount specific config:\\n  ///           maxTokenAmount = amountParams[0], Maximum token amount per address\\n  ///           maxSupplyAmount = amountParams[1], Maximum token token supply amount\\n\\n  constructor(\\n    string memory name_,\\n    string memory symbol_,\\n    uint256 initialSupplyToSet,\\n    uint8 decimalsToSet,\\n    address tokenOwner,\\n    ERC20ConfigProps memory customConfigProps,\\n    string memory newDocumentUri,\\n    address _taxAddress,\\n    uint256[3] memory bpsParams,\\n    uint256[2] memory amountParams\\n  )\\n    ReflectiveERC20(\\n      name_,\\n      symbol_,\\n      tokenOwner,\\n      initialSupplyToSet,\\n      decimalsToSet,\\n      initialSupplyToSet != 0 ? bpsParams[2] : 0,\\n      customConfigProps._isReflective\\n    )\\n  {\\n    // reflection feature can't be used in combination with burning/minting/deflation\\n    // or reflection config is invalid if no reflection BPS amount is provided\\n    if (\\n      (customConfigProps._isReflective &&\\n        (customConfigProps._isBurnable ||\\n          customConfigProps._isMintable ||\\n          customConfigProps._isDeflationary)) ||\\n      (!customConfigProps._isReflective && bpsParams[2] != 0)\\n    ) {\\n      revert InvalidReflectiveConfig();\\n    }\\n\\n    if (customConfigProps._isMaxAmountOfTokensSet) {\\n      if (amountParams[0] == 0) {\\n        revert InvalidMaxTokenAmount(amountParams[0]);\\n      }\\n    }\\n    if (decimalsToSet > 18) {\\n      revert InvalidDecimals(decimalsToSet);\\n    }\\n\\n    if (\\n      customConfigProps._isMaxSupplySet &&\\n      (!customConfigProps._isMintable || (totalSupply() > amountParams[1]))\\n    ) {\\n      revert InvalidMaxSupplyConfig();\\n    }\\n\\n    bpsInitChecks(customConfigProps, bpsParams, _taxAddress);\\n\\n    LibCommon.validateAddress(tokenOwner);\\n\\n    taxAddress = _taxAddress;\\n\\n    taxBPS = bpsParams[0];\\n    deflationBPS = bpsParams[1];\\n    initialSupply = initialSupplyToSet;\\n    initialMaxTokenAmountPerAddress = amountParams[0];\\n    initialDocumentUri = newDocumentUri;\\n    initialTokenOwner = tokenOwner;\\n    _decimals = decimalsToSet;\\n    configProps = customConfigProps;\\n    documentUri = newDocumentUri;\\n    maxTokenAmountPerAddress = amountParams[0];\\n    maxTotalSupply = amountParams[1];\\n\\n    if (tokenOwner != msg.sender) {\\n      transferOwnership(tokenOwner);\\n    }\\n  }\\n\\n  function bpsInitChecks(\\n    ERC20ConfigProps memory customConfigProps,\\n    uint256[3] memory bpsParams,\\n    address _taxAddress\\n  ) private pure {\\n    uint256 totalBPS = 0;\\n    if (customConfigProps._isTaxable) {\\n      LibCommon.validateAddress(_taxAddress);\\n\\n      totalBPS += bpsParams[0];\\n    }\\n    if (customConfigProps._isDeflationary) {\\n      totalBPS += bpsParams[1];\\n    }\\n    if (customConfigProps._isReflective) {\\n      totalBPS += bpsParams[2];\\n    }\\n    if (totalBPS > MAX_ALLOWED_BPS) {\\n      revert InvalidTotalBPS(totalBPS);\\n    }\\n  }\\n\\n  // Public and External Functions\\n\\n  /// @notice Checks if the token is mintable\\n  /// @return True if the token can be minted\\n  function isMintable() public view returns (bool) {\\n    return configProps._isMintable;\\n  }\\n\\n  /// @notice Checks if the token is burnable\\n  /// @return True if the token can be burned\\n  function isBurnable() public view returns (bool) {\\n    return configProps._isBurnable;\\n  }\\n\\n  /// @notice Checks if the maximum amount of tokens per address is set\\n  /// @return True if there is a maximum limit for token amount per address\\n  function isMaxAmountOfTokensSet() public view returns (bool) {\\n    return configProps._isMaxAmountOfTokensSet;\\n  }\\n\\n  /// @notice Checks if the maximum amount of token supply is set\\n  /// @return True if there is a maximum limit for token supply\\n  function isMaxSupplySet() public view returns (bool) {\\n    return configProps._isMaxSupplySet;\\n  }\\n\\n  /// @notice Checks if setting a document URI is allowed\\n  /// @return True if setting a document URI is allowed\\n  function isDocumentUriAllowed() public view returns (bool) {\\n    return configProps._isDocumentAllowed;\\n  }\\n\\n  /// @notice Returns the number of decimals used for the token\\n  /// @return The number of decimals\\n  function decimals() public view virtual override returns (uint8) {\\n    return _decimals;\\n  }\\n\\n  /// @notice Checks if the token is taxable\\n  /// @return True if the token has tax applied on transfers\\n  function isTaxable() public view returns (bool) {\\n    return configProps._isTaxable;\\n  }\\n\\n  /// @notice Checks if the token is deflationary\\n  /// @return True if the token has deflation applied on transfers\\n  function isDeflationary() public view returns (bool) {\\n    return configProps._isDeflationary;\\n  }\\n\\n  /// @notice Checks if the token is reflective\\n  /// @return True if the token has reflection (ie. holder rewards) applied on transfers\\n  function isReflective() public view returns (bool) {\\n    return configProps._isReflective;\\n  }\\n\\n  /// @notice Sets a new document URI\\n  /// @dev Can only be called by the contract owner\\n  /// @param newDocumentUri The new URI to be set\\n  function setDocumentUri(string memory newDocumentUri) external onlyOwner {\\n    if (!isDocumentUriAllowed()) {\\n      revert DocumentUriNotAllowed();\\n    }\\n    documentUri = newDocumentUri;\\n    emit DocumentUriSet(newDocumentUri);\\n  }\\n\\n  /// @notice Sets a new maximum token amount per address\\n  /// @dev Can only be called by the contract owner\\n  /// @param newMaxTokenAmount The new maximum token amount per address\\n  function setMaxTokenAmountPerAddress(\\n    uint256 newMaxTokenAmount\\n  ) external onlyOwner {\\n    if (!isMaxAmountOfTokensSet()) {\\n      revert MaxTokenAmountNotAllowed();\\n    }\\n    if (newMaxTokenAmount <= maxTokenAmountPerAddress) {\\n      revert MaxTokenAmountPerAddrLtPrevious();\\n    }\\n\\n    maxTokenAmountPerAddress = newMaxTokenAmount;\\n    emit MaxTokenAmountPerSet(newMaxTokenAmount);\\n  }\\n\\n  /// @notice Sets a new reflection fee\\n  /// @dev Can only be called by the contract owner\\n  /// @param _feeBPS The reflection fee in basis points\\n  function setReflectionConfig(uint256 _feeBPS) external onlyOwner {\\n    if (!isReflective()) {\\n      revert TokenIsNotReflective();\\n    }\\n    super._setReflectionFee(_feeBPS);\\n\\n    emit ReflectionConfigSet(_feeBPS);\\n  }\\n\\n  /// @notice Sets a new tax configuration\\n  /// @dev Can only be called by the contract owner\\n  /// @param _taxAddress The address where tax will be sent\\n  /// @param _taxBPS The tax rate in basis points\\n  function setTaxConfig(\\n    address _taxAddress,\\n    uint256 _taxBPS\\n  ) external onlyOwner {\\n    if (!isTaxable()) {\\n      revert TokenIsNotTaxable();\\n    }\\n\\n    uint256 totalBPS = deflationBPS + tFeeBPS + _taxBPS;\\n    if (totalBPS > MAX_ALLOWED_BPS) {\\n      revert InvalidTotalBPS(totalBPS);\\n    }\\n    LibCommon.validateAddress(_taxAddress);\\n    taxAddress = _taxAddress;\\n    taxBPS = _taxBPS;\\n    emit TaxConfigSet(_taxAddress, _taxBPS);\\n  }\\n\\n  /// @notice Sets a new deflation configuration\\n  /// @dev Can only be called by the contract owner\\n  /// @param _deflationBPS The deflation rate in basis points\\n  function setDeflationConfig(uint256 _deflationBPS) external onlyOwner {\\n    if (!isDeflationary()) {\\n      revert TokenIsNotDeflationary();\\n    }\\n    uint256 totalBPS = deflationBPS + tFeeBPS + _deflationBPS;\\n    if (totalBPS > MAX_ALLOWED_BPS) {\\n      revert InvalidTotalBPS(totalBPS);\\n    }\\n    deflationBPS = _deflationBPS;\\n    emit DeflationConfigSet(_deflationBPS);\\n  }\\n\\n  /// @notice Transfers tokens to a specified address\\n  /// @dev Overrides the ERC20 transfer function with added tax and deflation logic\\n  /// @param to The address to transfer tokens to\\n  /// @param amount The amount of tokens to be transferred\\n  /// @return True if the transfer was successful\\n  function transfer(\\n    address to,\\n    uint256 amount\\n  ) public virtual override returns (bool) {\\n    uint256 taxAmount = _taxAmount(msg.sender, amount);\\n    uint256 deflationAmount = _deflationAmount(amount);\\n    uint256 amountToTransfer = amount - taxAmount - deflationAmount;\\n\\n    if (isMaxAmountOfTokensSet()) {\\n      if (balanceOf(to) + amountToTransfer > maxTokenAmountPerAddress) {\\n        revert DestBalanceExceedsMaxAllowed(to);\\n      }\\n    }\\n\\n    if (taxAmount != 0) {\\n      _transferNonReflectedTax(msg.sender, taxAddress, taxAmount);\\n    }\\n    if (deflationAmount != 0) {\\n      _burn(msg.sender, deflationAmount);\\n    }\\n    return super.transfer(to, amountToTransfer);\\n  }\\n\\n  /// @notice Transfers tokens from one address to another\\n  /// @dev Overrides the ERC20 transferFrom function with added tax and deflation logic\\n  /// @param from The address which you want to send tokens from\\n  /// @param to The address which you want to transfer to\\n  /// @param amount The amount of tokens to be transferred\\n  /// @return True if the transfer was successful\\n  function transferFrom(\\n    address from,\\n    address to,\\n    uint256 amount\\n  ) public virtual override returns (bool) {\\n    uint256 taxAmount = _taxAmount(from, amount);\\n    uint256 deflationAmount = _deflationAmount(amount);\\n    uint256 amountToTransfer = amount - taxAmount - deflationAmount;\\n\\n    if (isMaxAmountOfTokensSet()) {\\n      if (balanceOf(to) + amountToTransfer > maxTokenAmountPerAddress) {\\n        revert DestBalanceExceedsMaxAllowed(to);\\n      }\\n    }\\n\\n    if (taxAmount != 0) {\\n      _transferNonReflectedTax(from, taxAddress, taxAmount);\\n    }\\n    if (deflationAmount != 0) {\\n      _burn(from, deflationAmount);\\n    }\\n\\n    return super.transferFrom(from, to, amountToTransfer);\\n  }\\n\\n  /// @notice Mints new tokens to a specified address\\n  /// @dev Can only be called by the contract owner and if minting is enabled\\n  /// @param to The address to mint tokens to\\n  /// @param amount The amount of tokens to mint\\n  function mint(address to, uint256 amount) external onlyOwner {\\n    if (!isMintable()) {\\n      revert MintingNotEnabled();\\n    }\\n    if (isMaxAmountOfTokensSet()) {\\n      if (balanceOf(to) + amount > maxTokenAmountPerAddress) {\\n        revert DestBalanceExceedsMaxAllowed(to);\\n      }\\n    }\\n    if (isMaxSupplySet()) {\\n      if (totalSupply() + amount > maxTotalSupply) {\\n        revert TotalSupplyExceedsMaxAllowedAmount();\\n      }\\n    }\\n\\n    super._mint(to, amount);\\n  }\\n\\n  /// @notice Burns a specific amount of tokens\\n  /// @dev Can only be called by the contract owner and if burning is enabled\\n  /// @param amount The amount of tokens to be burned\\n  function burn(uint256 amount) external onlyOwner {\\n    if (!isBurnable()) {\\n      revert BurningNotEnabled();\\n    }\\n    _burn(msg.sender, amount);\\n  }\\n\\n  /// @notice Renounces ownership of the contract\\n  /// @dev Leaves the contract without an owner, disabling any functions that require the owner's authorization\\n  function renounceOwnership() public override onlyOwner {\\n    super.renounceOwnership();\\n  }\\n\\n  /// @notice Transfers ownership of the contract to a new account\\n  /// @dev Can only be called by the current owner\\n  /// @param newOwner The address of the new owner\\n  function transferOwnership(address newOwner) public override onlyOwner {\\n    super.transferOwnership(newOwner);\\n  }\\n\\n  // Internal Functions\\n\\n  /// @notice Calculates the tax amount for a transfer\\n  /// @param sender The address initiating the transfer\\n  /// @param amount The amount of tokens being transferred\\n  /// @return taxAmount The calculated tax amount\\n  function _taxAmount(\\n    address sender,\\n    uint256 amount\\n  ) internal view returns (uint256 taxAmount) {\\n    taxAmount = 0;\\n    if (taxBPS != 0 && sender != taxAddress) {\\n      taxAmount = (amount * taxBPS) / MAX_BPS_AMOUNT;\\n    }\\n  }\\n\\n  /// @notice Calculates the deflation amount for a transfer\\n  /// @param amount The amount of tokens being transferred\\n  /// @return deflationAmount The calculated deflation amount\\n  function _deflationAmount(\\n    uint256 amount\\n  ) internal view returns (uint256 deflationAmount) {\\n    deflationAmount = 0;\\n    if (deflationBPS != 0) {\\n      deflationAmount = (amount * deflationBPS) / MAX_BPS_AMOUNT;\\n    }\\n  }\\n}\\n\",\"keccak256\":\"0x8b5e8867c3ce6f028c3eac9fbe0c2e939ea20192e6d720bda51ec1ec38626763\",\"license\":\"GPL-3.0\"},\"contracts/ReflectiveERC20.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.17;\\n\\nimport { ERC20 } from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport { LibCommon } from \\\"./lib/LibCommon.sol\\\";\\n\\n/// @title A ERC20 implementation with extended reflection token functionalities\\n/// @notice Implements ERC20 standards with additional token holder reward feature\\nabstract contract ReflectiveERC20 is ERC20 {\\n  // Constants\\n  uint256 private constant BPS_DIVISOR = 10_000;\\n\\n  mapping(address => uint256) private _rOwned;\\n  mapping(address => uint256) private _tOwned;\\n\\n  uint256 private constant UINT_256_MAX = type(uint256).max;\\n  uint256 private _rTotal;\\n  uint256 private _tFeeTotal;\\n\\n  uint256 public tFeeBPS;\\n  bool private immutable isReflective;\\n\\n  // custom errors\\n  error TokenIsNotReflective();\\n  error TotalReflectionTooSmall();\\n  error ZeroTransferError();\\n  error MintingNotEnabled();\\n  error BurningNotEnabled();\\n  error ERC20InsufficientBalance(\\n    address recipient,\\n    uint256 fromBalance,\\n    uint256 balance\\n  );\\n\\n  /// @notice Gets total supply of the erc20 token\\n  /// @return Token total supply\\n  function _tTotal() public view virtual returns (uint256) {\\n    return totalSupply();\\n  }\\n\\n  /// @notice Constructor to initialize the ReflectionErc20 token\\n  /// @param name_ Name of the token\\n  /// @param symbol_ Symbol of the token\\n  /// @param tokenOwner Address of the token owner\\n  /// @param totalSupply_ Initial total supply\\n  /// @param decimalsToSet Token decimal number\\n  /// @param decimalsToSet Token reward (reflection fee BPS value\\n  constructor(\\n    string memory name_,\\n    string memory symbol_,\\n    address tokenOwner,\\n    uint256 totalSupply_,\\n    uint8 decimalsToSet,\\n    uint256 tFeeBPS_,\\n    bool isReflective_\\n  ) ERC20(name_, symbol_) {\\n    if (totalSupply_ != 0) {\\n      super._mint(tokenOwner, totalSupply_ * 10 ** decimalsToSet);\\n      _rTotal = (UINT_256_MAX - (UINT_256_MAX % totalSupply_));\\n    }\\n\\n    _rOwned[tokenOwner] = _rTotal;\\n    tFeeBPS = tFeeBPS_;\\n    isReflective = isReflective_;\\n  }\\n\\n  // public standard ERC20 functions\\n\\n  /// @notice Gets balance the erc20 token for specific address\\n  /// @param account Account address\\n  /// @return Token balance\\n  function balanceOf(address account) public view override returns (uint256) {\\n    if (isReflective) {\\n      return tokenFromReflection(_rOwned[account]);\\n    } else {\\n      return super.balanceOf(account);\\n    }\\n  }\\n\\n  /// @notice Transfers allowed tokens between accounts\\n  /// @param from From account\\n  /// @param to To account\\n  /// @param value Transferred value\\n  /// @return Success\\n  function transferFrom(\\n    address from,\\n    address to,\\n    uint256 value\\n  ) public virtual override returns (bool) {\\n    address spender = super._msgSender();\\n    _spendAllowance(from, spender, value);\\n    _transfer(from, to, value);\\n    return true;\\n  }\\n\\n  /// @notice Transfers tokens from owner to an account\\n  /// @param to To account\\n  /// @param value Transferred value\\n  /// @return Success\\n  function transfer(\\n    address to,\\n    uint256 value\\n  ) public virtual override returns (bool) {\\n    address owner = super._msgSender();\\n    _transfer(owner, to, value);\\n    return true;\\n  }\\n\\n  // override internal OZ standard ERC20 functions related to transfer\\n\\n  /// @notice Transfers tokens from owner to an account\\n  /// @param to To account\\n  /// @param amount Transferred amount\\n  function _transfer(\\n    address from,\\n    address to,\\n    uint256 amount\\n  ) internal override {\\n    if (isReflective) {\\n      LibCommon.validateAddress(from);\\n      LibCommon.validateAddress(to);\\n      if (amount == 0) {\\n        revert ZeroTransferError();\\n      }\\n\\n      _transferReflected(from, to, amount);\\n    } else {\\n      super._transfer(from, to, amount);\\n    }\\n  }\\n\\n  // override incompatible internal OZ standard ERC20 functions to disable them in case\\n  // reflection mechanism is used, ie. tFeeBPS is non zero\\n\\n  /// @notice Creates specified amount of tokens, it either uses standard OZ ERC function\\n  ///         or in case of reflection logic, it is prohibited\\n  /// @param account Account new tokens will be transferred to\\n  /// @param value Created tokens value\\n  function _mint(address account, uint256 value) internal override {\\n    if (isReflective) {\\n      revert MintingNotEnabled();\\n    } else {\\n      super._mint(account, value);\\n    }\\n  }\\n\\n  /// @notice Destroys specified amount of tokens, it either uses standard OZ ERC function\\n  ///         or in case of reflection logic, it is prohibited\\n  /// @param account Account in which tokens will be destroyed\\n  /// @param value Destroyed tokens value\\n  function _burn(address account, uint256 value) internal override {\\n    if (isReflective) {\\n      revert BurningNotEnabled();\\n    } else {\\n      super._burn(account, value);\\n    }\\n  }\\n\\n  // public reflection custom functions\\n\\n  /// @notice Sets a new reflection fee\\n  /// @dev Should only be called by the contract owner\\n  /// @param _tFeeBPS The reflection fee in basis points\\n  function _setReflectionFee(uint256 _tFeeBPS) internal {\\n    if (!isReflective) {\\n      revert TokenIsNotReflective();\\n    }\\n\\n    tFeeBPS = _tFeeBPS;\\n  }\\n\\n  /// @notice Calculates number of tokens from reflection amount\\n  /// @param rAmount Reflection token amount\\n  function tokenFromReflection(uint256 rAmount) public view returns (uint256) {\\n    if (rAmount > _rTotal) {\\n      revert TotalReflectionTooSmall();\\n    }\\n\\n    uint256 currentRate = _getRate();\\n    return rAmount / currentRate;\\n  }\\n\\n  // private reflection custom functions\\n\\n  /// @notice Transfers reflected amount of tokens\\n  /// @param sender Account to transfer tokens from\\n  /// @param recipient Account to transfer tokens to\\n  /// @param tAmount Total token amount\\n  function _transferReflected(\\n    address sender,\\n    address recipient,\\n    uint256 tAmount\\n  ) private {\\n    uint256 tFee = calculateFee(tAmount);\\n    uint256 tTransferAmount = tAmount - tFee;\\n    (uint256 rAmount, uint256 rFee, uint256 rTransferAmount) = _getRValues(\\n      tAmount,\\n      tFee,\\n      tTransferAmount\\n    );\\n\\n    if (tAmount != 0) {\\n      _rUpdate(sender, recipient, rAmount, rTransferAmount);\\n\\n      _reflectFee(rFee, tFee);\\n      emit Transfer(sender, recipient, tAmount);\\n    }\\n  }\\n\\n  /// @notice Deducts reflection fee from reflection supply to 'distribute' token holder rewards\\n  /// @param rFee Reflection fee\\n  /// @param tFee Token fee\\n  function _reflectFee(uint256 rFee, uint256 tFee) private {\\n    _rTotal = _rTotal - rFee;\\n    _tFeeTotal = _tFeeTotal + tFee;\\n  }\\n\\n  /// @notice Calculates the reflection fee from token amount\\n  /// @param _amount Amount of tokens to calculate fee from\\n  function calculateFee(uint256 _amount) private view returns (uint256) {\\n    return (_amount * tFeeBPS) / BPS_DIVISOR;\\n  }\\n\\n  /// @notice Transfers Tax related tokens and do not apply reflection fees\\n  /// @param from Account to transfer tokens from\\n  /// @param to Account to transfer tokens to\\n  /// @param tAmount Total token amount\\n  function _transferNonReflectedTax(\\n    address from,\\n    address to,\\n    uint256 tAmount\\n  ) internal {\\n    if (isReflective) {\\n      if (tAmount != 0) {\\n        uint256 currentRate = _getRate();\\n        uint256 rAmount = tAmount * currentRate;\\n\\n        _rUpdate(from, to, rAmount, rAmount);\\n        emit Transfer(from, to, tAmount);\\n      }\\n    } else {\\n      super._transfer(from, to, tAmount);\\n    }\\n  }\\n\\n  /// @notice Get reflective values from token values\\n  /// @param tAmount Token amount\\n  /// @param tFee Token fee\\n  /// @param tTransferAmount Transfer amount\\n  function _getRValues(\\n    uint256 tAmount,\\n    uint256 tFee,\\n    uint256 tTransferAmount\\n  ) private view returns (uint256, uint256, uint256) {\\n    uint256 currentRate = _getRate();\\n    uint256 rAmount = tAmount * currentRate;\\n    uint256 rFee = tFee * currentRate;\\n    uint256 rTransferAmount = tTransferAmount * currentRate;\\n\\n    return (rAmount, rFee, rTransferAmount);\\n  }\\n\\n  /// @notice Get ratio rate between reflective and token supply\\n  /// @return Reflective rate\\n  function _getRate() private view returns (uint256) {\\n    (uint256 rSupply, uint256 tSupply) = _getCurrentSupply();\\n    return rSupply / tSupply;\\n  }\\n\\n  /// @notice Get reflective and token supplies\\n  /// @return Reflective and token supplies\\n  function _getCurrentSupply() private view returns (uint256, uint256) {\\n    return (_rTotal, _tTotal());\\n  }\\n\\n  /// @notice Update reflective balances to reflect amount transfer,\\n  ///         with or without a fee applied. If a fee is applied,\\n  ///         the amount deducted from the sender will differ\\n  ///         from amount added to the recipient\\n  /// @param sender Sender address\\n  /// @param recipient Recipient address\\n  /// @param rSubAmount Amount to be deducted from sender\\n  /// @param rTransferAmount Amount to be added to recipient\\n  function _rUpdate(\\n    address sender,\\n    address recipient,\\n    uint256 rSubAmount,\\n    uint256 rTransferAmount\\n  ) private {\\n    uint256 fromBalance = _rOwned[sender];\\n    if (fromBalance < rSubAmount) {\\n      revert ERC20InsufficientBalance(recipient, fromBalance, rSubAmount);\\n    }\\n    _rOwned[sender] = _rOwned[sender] - rSubAmount;\\n    _rOwned[recipient] = _rOwned[recipient] + rTransferAmount;\\n  }\\n}\\n\",\"keccak256\":\"0x22a919e286fb96030b6d0c102478dfb504d2d59e16f8a62baaeed6464a344fdd\",\"license\":\"GPL-3.0\"},\"contracts/lib/LibCommon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.17;\\n\\nlibrary LibCommon {\\n  /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\\n  /*                       CUSTOM ERRORS                        */\\n  /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\\n\\n  /// @dev The ETH transfer has failed.\\n  error ETHTransferFailed();\\n\\n  /// @dev The address is the zero address.\\n  error ZeroAddress();\\n\\n  /// @notice raised when an ERC20 transfer fails\\n  error TransferFailed();\\n\\n  /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\\n  /*                       ETH OPERATIONS                       */\\n  /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\\n\\n  /// @notice Taken from Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)\\n  /// @dev Sends `amount` (in wei) ETH to `to`.\\n  /// Reverts upon failure.\\n  function safeTransferETH(address to, uint256 amount) internal {\\n    // solhint-disable-next-line no-inline-assembly\\n    assembly {\\n      // Transfer the ETH and check if it succeeded or not.\\n      if iszero(call(gas(), to, amount, 0, 0, 0, 0)) {\\n        // Store the function selector of `ETHTransferFailed()`.\\n        // bytes4(keccak256(bytes(\\\"ETHTransferFailed()\\\"))) = 0xb12d13eb\\n        mstore(0x00, 0xb12d13eb)\\n        // Revert with (offset, size).\\n        revert(0x1c, 0x04)\\n      }\\n    }\\n  }\\n\\n  /// @notice Validates that the address is not the zero address using assembly.\\n  /// @dev Reverts if the address is the zero address.\\n  function validateAddress(address addr) internal pure {\\n    // solhint-disable-next-line no-inline-assembly\\n    assembly {\\n      if iszero(shl(96, addr)) {\\n        // Store the function selector of `ZeroAddress()`.\\n        // bytes4(keccak256(bytes(\\\"ZeroAddress()\\\"))) = 0xd92e233d\\n        mstore(0x00, 0xd92e233d)\\n        // Revert with (offset, size).\\n        revert(0x1c, 0x04)\\n      }\\n    }\\n  }\\n\\n  /// @notice Helper function to transfer ERC20 tokens without the need for SafeERC20.\\n  /// @dev Reverts if the ERC20 transfer fails.\\n  /// @param tokenAddress The address of the ERC20 token.\\n  /// @param from The address to transfer the tokens from.\\n  /// @param to The address to transfer the tokens to.\\n  /// @param amount The amount of tokens to transfer.\\n  function safeTransferFrom(\\n    address tokenAddress,\\n    address from,\\n    address to,\\n    uint256 amount\\n  ) internal returns (bool) {\\n    // solhint-disable-next-line avoid-low-level-calls\\n    (bool success, bytes memory data) = tokenAddress.call(\\n      abi.encodeWithSignature(\\n        \\\"transferFrom(address,address,uint256)\\\",\\n        from,\\n        to,\\n        amount\\n      )\\n    );\\n    if (!success) {\\n      if (data.length != 0) {\\n        // bubble up error\\n        // solhint-disable-next-line no-inline-assembly\\n        assembly {\\n          let returndata_size := mload(data)\\n          revert(add(32, data), returndata_size)\\n        }\\n      } else {\\n        revert TransferFailed();\\n      }\\n    }\\n    return true;\\n  }\\n\\n  /// @notice Helper function to transfer ERC20 tokens without the need for SafeERC20.\\n  /// @dev Reverts if the ERC20 transfer fails.\\n  /// @param tokenAddress The address of the ERC20 token.\\n  /// @param to The address to transfer the tokens to.\\n  /// @param amount The amount of tokens to transfer.\\n  function safeTransfer(\\n    address tokenAddress,\\n    address to,\\n    uint256 amount\\n  ) internal returns (bool) {\\n    // solhint-disable-next-line avoid-low-level-calls\\n    (bool success, bytes memory data) = tokenAddress.call(\\n      abi.encodeWithSignature(\\\"transfer(address,uint256)\\\", to, amount)\\n    );\\n    if (!success) {\\n      if (data.length != 0) {\\n        // bubble up error\\n        // solhint-disable-next-line no-inline-assembly\\n        assembly {\\n          let returndata_size := mload(data)\\n          revert(add(32, data), returndata_size)\\n        }\\n      } else {\\n        revert TransferFailed();\\n      }\\n    }\\n    return true;\\n  }\\n}\\n\",\"keccak256\":\"0x55b4e5340734e424b2ce425593e84ebfc01453c507d97f699892001321529d52\",\"license\":\"MIT\"}},\"version\":1}","userdoc":{"kind":"user","notice":"Implements ERC20 standards with additional features like tax and deflation","methods":{"_tTotal()":{"notice":"Gets total supply of the erc20 token"},"decimals()":{"notice":"Returns the number of decimals used for the token"},"constructor":{"notice":"Constructor to initialize the DeFi token"},"isTaxable()":{"notice":"Checks if the token is taxable"},"isBurnable()":{"notice":"Checks if the token is burnable"},"isMintable()":{"notice":"Checks if the token is mintable"},"burn(uint256)":{"notice":"Burns a specific amount of tokens"},"isReflective()":{"notice":"Checks if the token is reflective"},"isDeflationary()":{"notice":"Checks if the token is deflationary"},"isMaxSupplySet()":{"notice":"Checks if the maximum amount of token supply is set"},"balanceOf(address)":{"notice":"Gets balance the erc20 token for specific address"},"renounceOwnership()":{"notice":"Renounces ownership of the contract"},"mint(address,uint256)":{"notice":"Mints new tokens to a specified address"},"isDocumentUriAllowed()":{"notice":"Checks if setting a document URI is allowed"},"setDocumentUri(string)":{"notice":"Sets a new document URI"},"isMaxAmountOfTokensSet()":{"notice":"Checks if the maximum amount of tokens per address is set"},"transfer(address,uint256)":{"notice":"Transfers tokens to a specified address"},"transferOwnership(address)":{"notice":"Transfers ownership of the contract to a new account"},"setDeflationConfig(uint256)":{"notice":"Sets a new deflation configuration"},"setReflectionConfig(uint256)":{"notice":"Sets a new reflection fee"},"tokenFromReflection(uint256)":{"notice":"Calculates number of tokens from reflection amount"},"setTaxConfig(address,uint256)":{"notice":"Sets a new tax configuration"},"setMaxTokenAmountPerAddress(uint256)":{"notice":"Sets a new maximum token amount per address"},"transferFrom(address,address,uint256)":{"notice":"Transfers tokens from one address to another"}},"version":1},"devdoc":{"kind":"dev","title":"A Defi Token implementation with extended functionalities","methods":{"name()":{"details":"Returns the name of the token."},"owner()":{"details":"Returns the address of the current owner."},"symbol()":{"details":"Returns the symbol of the token, usually a shorter version of the name."},"_tTotal()":{"returns":{"_0":"Token total supply"}},"decimals()":{"returns":{"_0":"The number of decimals"}},"constructor":{"params":{"name_":"Name of the token","symbol_":"Symbol of the token","bpsParams":"array of BPS values in this order:           taxBPS = bpsParams[0],           deflationBPS = bpsParams[1],           rewardFeeBPS = bpsParams[2],","tokenOwner":"Address of the initial token owner","_taxAddress":"Address where tax will be sent","amountParams":"array of amounts for amount specific config:           maxTokenAmount = amountParams[0], Maximum token amount per address           maxSupplyAmount = amountParams[1], Maximum token token supply amount","decimalsToSet":"Number of decimals for the token","newDocumentUri":"URI for the document associated with the token","customConfigProps":"Configuration properties for the token","initialSupplyToSet":"Initial supply of tokens"}},"isTaxable()":{"returns":{"_0":"True if the token has tax applied on transfers"}},"isBurnable()":{"returns":{"_0":"True if the token can be burned"}},"isMintable()":{"returns":{"_0":"True if the token can be minted"}},"burn(uint256)":{"params":{"amount":"The amount of tokens to be burned"},"details":"Can only be called by the contract owner and if burning is enabled"},"totalSupply()":{"details":"See {IERC20-totalSupply}."},"isReflective()":{"returns":{"_0":"True if the token has reflection (ie. holder rewards) applied on transfers"}},"isDeflationary()":{"returns":{"_0":"True if the token has deflation applied on transfers"}},"isMaxSupplySet()":{"returns":{"_0":"True if there is a maximum limit for token supply"}},"balanceOf(address)":{"params":{"account":"Account address"},"returns":{"_0":"Token balance"}},"renounceOwnership()":{"details":"Leaves the contract without an owner, disabling any functions that require the owner's authorization"},"mint(address,uint256)":{"params":{"to":"The address to mint tokens to","amount":"The amount of tokens to mint"},"details":"Can only be called by the contract owner and if minting is enabled"},"isDocumentUriAllowed()":{"returns":{"_0":"True if setting a document URI is allowed"}},"setDocumentUri(string)":{"params":{"newDocumentUri":"The new URI to be set"},"details":"Can only be called by the contract owner"},"approve(address,uint256)":{"details":"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address."},"isMaxAmountOfTokensSet()":{"returns":{"_0":"True if there is a maximum limit for token amount per address"}},"transfer(address,uint256)":{"params":{"to":"The address to transfer tokens to","amount":"The amount of tokens to be transferred"},"details":"Overrides the ERC20 transfer function with added tax and deflation logic","returns":{"_0":"True if the transfer was successful"}},"allowance(address,address)":{"details":"See {IERC20-allowance}."},"transferOwnership(address)":{"params":{"newOwner":"The address of the new owner"},"details":"Can only be called by the current owner"},"setDeflationConfig(uint256)":{"params":{"_deflationBPS":"The deflation rate in basis points"},"details":"Can only be called by the contract owner"},"setReflectionConfig(uint256)":{"params":{"_feeBPS":"The reflection fee in basis points"},"details":"Can only be called by the contract owner"},"tokenFromReflection(uint256)":{"params":{"rAmount":"Reflection token amount"}},"setTaxConfig(address,uint256)":{"params":{"_taxBPS":"The tax rate in basis points","_taxAddress":"The address where tax will be sent"},"details":"Can only be called by the contract owner"},"decreaseAllowance(address,uint256)":{"details":"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`."},"increaseAllowance(address,uint256)":{"details":"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address."},"setMaxTokenAmountPerAddress(uint256)":{"params":{"newMaxTokenAmount":"The new maximum token amount per address"},"details":"Can only be called by the contract owner"},"transferFrom(address,address,uint256)":{"params":{"to":"The address which you want to transfer to","from":"The address which you want to send tokens from","amount":"The amount of tokens to be transferred"},"details":"Overrides the ERC20 transferFrom function with added tax and deflation logic","returns":{"_0":"True if the transfer was successful"}}},"version":1},"storageLayout":{"types":{"t_bool":{"label":"bool","encoding":"inplace","numberOfBytes":"1"},"t_address":{"label":"address","encoding":"inplace","numberOfBytes":"20"},"t_uint256":{"label":"uint256","encoding":"inplace","numberOfBytes":"32"},"t_string_storage":{"label":"string","encoding":"bytes","numberOfBytes":"32"},"t_mapping(t_address,t_uint256)":{"key":"t_address","label":"mapping(address => uint256)","value":"t_uint256","encoding":"mapping","numberOfBytes":"32"},"t_struct(ERC20ConfigProps)883_storage":{"label":"struct DefiV3Token.ERC20ConfigProps","members":[{"slot":"0","type":"t_bool","astId":868,"label":"_isMintable","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"0","type":"t_bool","astId":870,"label":"_isBurnable","offset":1,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"0","type":"t_bool","astId":872,"label":"_isDocumentAllowed","offset":2,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"0","type":"t_bool","astId":874,"label":"_isMaxAmountOfTokensSet","offset":3,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"0","type":"t_bool","astId":876,"label":"_isMaxSupplySet","offset":4,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"0","type":"t_bool","astId":878,"label":"_isTaxable","offset":5,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"0","type":"t_bool","astId":880,"label":"_isDeflationary","offset":6,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"0","type":"t_bool","astId":882,"label":"_isReflective","offset":7,"contract":"contracts/DefiV3Token.sol:DefiV3Token"}],"encoding":"inplace","numberOfBytes":"32"},"t_mapping(t_address,t_mapping(t_address,t_uint256))":{"key":"t_address","label":"mapping(address => mapping(address => uint256))","value":"t_mapping(t_address,t_uint256)","encoding":"mapping","numberOfBytes":"32"}},"storage":[{"slot":"0","type":"t_mapping(t_address,t_uint256)","astId":128,"label":"_balances","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"1","type":"t_mapping(t_address,t_mapping(t_address,t_uint256))","astId":134,"label":"_allowances","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"2","type":"t_uint256","astId":136,"label":"_totalSupply","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"3","type":"t_string_storage","astId":138,"label":"_name","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"4","type":"t_string_storage","astId":140,"label":"_symbol","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"5","type":"t_mapping(t_address,t_uint256)","astId":1833,"label":"_rOwned","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"6","type":"t_mapping(t_address,t_uint256)","astId":1837,"label":"_tOwned","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"7","type":"t_uint256","astId":1846,"label":"_rTotal","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"8","type":"t_uint256","astId":1848,"label":"_tFeeTotal","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"9","type":"t_uint256","astId":1850,"label":"tFeeBPS","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"10","type":"t_address","astId":7,"label":"_owner","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"11","type":"t_string_storage","astId":856,"label":"initialDocumentUri","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"12","type":"t_string_storage","astId":858,"label":"documentUri","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"13","type":"t_uint256","astId":864,"label":"maxTokenAmountPerAddress","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"14","type":"t_uint256","astId":866,"label":"maxTotalSupply","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"15","type":"t_struct(ERC20ConfigProps)883_storage","astId":886,"label":"configProps","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"16","type":"t_address","astId":892,"label":"taxAddress","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"17","type":"t_uint256","astId":894,"label":"taxBPS","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"},{"slot":"18","type":"t_uint256","astId":896,"label":"deflationBPS","offset":0,"contract":"contracts/DefiV3Token.sol:DefiV3Token"}]},"transientStorageLayout":null,"evm":{"bytecode":{"object":"6101206040523480156200001257600080fd5b5060405162002dd638038062002dd6833981016040819052620000359162000933565b8989878a8a8c6000036200004b57600062000051565b60408701515b60e08b01518686600362000066838262000ad3565b50600462000075828262000ad3565b50505083600014620000d057620000b0856200009385600a62000cb4565b6200009f908762000ccc565b620003b160201b6200100a1760201c565b620000be8460001962000ce6565b620000cc9060001962000d09565b6007555b6007546001600160a01b0390951660009081526005602052604090209490945560095550501515608052506200010f9050620001093390565b62000474565b8460e0015180156200013857508460200151806200012b575084515b806200013857508460c001515b806200015557508460e00151158015620001555750604082015115155b156200017457604051630c2a1c3360e21b815260040160405180910390fd5b846060015115620001ad578051600003620001ad5780516040516364824b8d60e01b815260048101919091526024015b60405180910390fd5b60128760ff161115620001d95760405163ca95039160e01b815260ff88166004820152602401620001a4565b84608001518015620001fa575084511580620001fa57506020810151600254115b156200021957604051635a8d424160e11b815260040160405180910390fd5b62000226858385620004c6565b6200023c866200056660201b620010c91760201c565b601080546001600160a01b0319166001600160a01b0385161790558151601155602082015160125560a0889052805160c052600b6200027c858262000ad3565b506001600160a01b03861660e090815260ff88166101009081528651600f805460208a015160408b015160608c015160808d015160a08e015160c08f0151998f015161ffff1990961697151561ff001916979097179315159097029290921763ffff00001916620100009115159190910263ff0000001916176301000000911515919091021761ffff60201b19166401000000009415159490940260ff60281b19169390931765010000000000921515929092029190911761ffff60301b191666010000000000009315159390930260ff60381b19169290921767010000000000000091151591909102179055600c62000377858262000ad3565b508051600d556020810151600e55336001600160a01b03871614620003a157620003a18662000580565b5050505050505050505062000d35565b6001600160a01b038216620004095760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401620001a4565b80600260008282546200041d919062000d1f565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60008360a0015115620004fa57620004e9826200056660201b620010c91760201c565b8251620004f7908262000d1f565b90505b8360c00151156200051957602083015162000516908262000d1f565b90505b8360e00151156200053857604083015162000535908262000d1f565b90505b6107d08111156200056057604051633e474e0d60e01b815260048101829052602401620001a4565b50505050565b8060601b6200057d5763d92e233d6000526004601cfd5b50565b6200058a620005a5565b6200057d816200060360201b620010df1760201c565b505050565b600a546001600160a01b03163314620006015760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620001a4565b565b6200060d620005a5565b6001600160a01b038116620006745760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401620001a4565b6200057d8162000474565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620006c057620006c06200067f565b604052919050565b600082601f830112620006da57600080fd5b81516001600160401b03811115620006f657620006f66200067f565b60206200070c601f8301601f1916820162000695565b82815285828487010111156200072157600080fd5b60005b838110156200074157858101830151828201840152820162000724565b506000928101909101919091529392505050565b805160ff811681146200076757600080fd5b919050565b80516001600160a01b03811681146200076757600080fd5b805180151581146200076757600080fd5b6000610100808385031215620007aa57600080fd5b604051908101906001600160401b0382118183101715620007cf57620007cf6200067f565b81604052809250620007e18462000784565b8152620007f16020850162000784565b6020820152620008046040850162000784565b6040820152620008176060850162000784565b60608201526200082a6080850162000784565b60808201526200083d60a0850162000784565b60a08201526200085060c0850162000784565b60c08201526200086360e0850162000784565b60e0820152505092915050565b600082601f8301126200088257600080fd5b604051606081016001600160401b0381118282101715620008a757620008a76200067f565b604052806060840185811115620008bd57600080fd5b845b81811015620008d9578051835260209283019201620008bf565b509195945050505050565b600082601f830112620008f657600080fd5b604080519081016001600160401b03811182821017156200091b576200091b6200067f565b8060405250806040840185811115620008bd57600080fd5b6000806000806000806000806000806102808b8d0312156200095457600080fd5b8a516001600160401b03808211156200096c57600080fd5b6200097a8e838f01620006c8565b9b5060208d01519150808211156200099157600080fd5b6200099f8e838f01620006c8565b9a5060408d01519950620009b660608e0162000755565b9850620009c660808e016200076c565b9750620009d78e60a08f0162000795565b96506101a08d0151915080821115620009ef57600080fd5b50620009fe8d828e01620006c8565b94505062000a106101c08c016200076c565b925062000a228c6101e08d0162000870565b915062000a348c6102408d01620008e4565b90509295989b9194979a5092959850565b600181811c9082168062000a5a57607f821691505b60208210810362000a7b57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620005a057600081815260208120601f850160051c8101602086101562000aaa5750805b601f850160051c820191505b8181101562000acb5782815560010162000ab6565b505050505050565b81516001600160401b0381111562000aef5762000aef6200067f565b62000b078162000b00845462000a45565b8462000a81565b602080601f83116001811462000b3f576000841562000b265750858301515b600019600386901b1c1916600185901b17855562000acb565b600085815260208120601f198616915b8281101562000b705788860151825594840194600190910190840162000b4f565b508582101562000b8f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b600181815b8085111562000bf657816000190482111562000bda5762000bda62000b9f565b8085161562000be857918102915b93841c939080029062000bba565b509250929050565b60008262000c0f5750600162000cae565b8162000c1e5750600062000cae565b816001811462000c37576002811462000c425762000c62565b600191505062000cae565b60ff84111562000c565762000c5662000b9f565b50506001821b62000cae565b5060208310610133831016604e8410600b841016171562000c87575081810a62000cae565b62000c93838362000bb5565b806000190482111562000caa5762000caa62000b9f565b0290505b92915050565b600062000cc560ff84168362000bfe565b9392505050565b808202811582820484141762000cae5762000cae62000b9f565b60008262000d0457634e487b7160e01b600052601260045260246000fd5b500690565b8181038181111562000cae5762000cae62000b9f565b8082018082111562000cae5762000cae62000b9f565b60805160a05160c05160e0516101005161203962000d9d60003960006103b3015260006104cc01526000610519015260006103e2015260008181610b1c0152818161138a0152818161143c015281816114c10152818161152a0152611a9301526120396000f3fe608060405234801561001057600080fd5b50600436106102e95760003560e01c8063883356d911610191578063af465a27116100e3578063de0060ca11610097578063f820f56711610071578063f820f56714610625578063f91f825d14610636578063ffa1ad741461064957600080fd5b8063de0060ca146105ec578063f19c4e3b146105ff578063f2fde38b1461061257600080fd5b8063d48e4127116100c8578063d48e412714610597578063d8f67851146105a0578063dd62ed3e146105b357600080fd5b8063af465a271461057c578063b7bda68f1461058457600080fd5b80639703a19d11610145578063a476df611161011f578063a476df611461054e578063a9059cbb14610561578063a9d866851461057457600080fd5b80639703a19d1461050b578063a32f697614610514578063a457c2d71461053b57600080fd5b80638dac7191116101765780638dac7191146104c75780638e8c10a2146104ee57806395d89b411461050357600080fd5b8063883356d9146104925780638da5cb5b146104a257600080fd5b8063313ce5671161024a57806346b45af7116101fe5780635a3990ce116101d85780635a3990ce1461046557806370a0823114610477578063715018a61461048a57600080fd5b806346b45af71461043d5780634ac0bc3214610448578063542e96671461045c57600080fd5b8063395093511161022f578063395093511461040457806340c10f191461041757806342966c681461042a57600080fd5b8063313ce567146103ac578063378dc3dc146103dd57600080fd5b806323b872dd116102a15780632d838119116102865780632d8381191461037a5780632e0ee48e1461038d5780632fa782eb146103a357600080fd5b806323b872dd1461035e5780632ab4d0521461037157600080fd5b806306fdde03116102d257806306fdde0314610321578063095ea7b31461032957806318160ddd1461034c57600080fd5b806302252c4d146102ee578063044ab74e14610303575b600080fd5b6103016102fc366004611c4d565b610685565b005b61030b610747565b6040516103189190611c66565b60405180910390f35b61030b6107d5565b61033c610337366004611ccb565b610867565b6040519015158152602001610318565b6002545b604051908152602001610318565b61033c61036c366004611cf5565b610881565b610350600e5481565b610350610388366004611c4d565b610953565b600f54670100000000000000900460ff1661033c565b61035060115481565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610318565b6103507f000000000000000000000000000000000000000000000000000000000000000081565b61033c610412366004611ccb565b6109ae565b610301610425366004611ccb565b6109ed565b610301610438366004611c4d565b610adb565b600f5460ff1661033c565b600f5465010000000000900460ff1661033c565b61035060125481565b600f546301000000900460ff1661033c565b610350610485366004611d31565b610b18565b610301610b85565b600f54610100900460ff1661033c565b600a546001600160a01b03165b6040516001600160a01b039091168152602001610318565b6104af7f000000000000000000000000000000000000000000000000000000000000000081565b600f546601000000000000900460ff1661033c565b61030b610b97565b61035060095481565b6103507f000000000000000000000000000000000000000000000000000000000000000081565b61033c610549366004611ccb565b610ba6565b61030161055c366004611d62565b610c5b565b61033c61056f366004611ccb565b610ce1565b61030b610dac565b610350610db9565b6010546104af906001600160a01b031681565b610350600d5481565b6103016105ae366004611c4d565b610dc9565b6103506105c1366004611e13565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b600f54640100000000900460ff1661033c565b61030161060d366004611ccb565b610e90565b610301610620366004611d31565b610f8c565b600f5462010000900460ff1661033c565b610301610644366004611c4d565b610f9d565b61030b6040518060400160405280600881526020017f646566695f765f3300000000000000000000000000000000000000000000000081525081565b61068d61116c565b600f546301000000900460ff166106d0576040517f6273340f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d54811161070b576040517fa43d2d7600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d8190556040518181527f2905481c6fd1a037492016c4760435a52203d82a6f34dc3de40f464c1bf42d59906020015b60405180910390a150565b600c805461075490611e46565b80601f016020809104026020016040519081016040528092919081815260200182805461078090611e46565b80156107cd5780601f106107a2576101008083540402835291602001916107cd565b820191906000526020600020905b8154815290600101906020018083116107b057829003601f168201915b505050505081565b6060600380546107e490611e46565b80601f016020809104026020016040519081016040528092919081815260200182805461081090611e46565b801561085d5780601f106108325761010080835404028352916020019161085d565b820191906000526020600020905b81548152906001019060200180831161084057829003601f168201915b5050505050905090565b6000336108758185856111c6565b60019150505b92915050565b60008061088e858461131e565b9050600061089b84611361565b90506000816108aa8487611e96565b6108b49190611e96565b600f549091506301000000900460ff161561090f57600d54816108d688610b18565b6108e09190611ea9565b111561090f5760405163f6202a8f60e01b81526001600160a01b03871660048201526024015b60405180910390fd5b821561092d5760105461092d9088906001600160a01b031685611388565b811561093d5761093d878361143a565b610948878783611483565b979650505050505050565b6000600754821115610991576040517fc91fa8bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061099b61149c565b90506109a78184611ebc565b9392505050565b3360008181526001602090815260408083206001600160a01b038716845290915281205490919061087590829086906109e8908790611ea9565b6111c6565b6109f561116c565b600f5460ff16610a1857604051630732158d60e31b815260040160405180910390fd5b600f546301000000900460ff1615610a6b57600d5481610a3784610b18565b610a419190611ea9565b1115610a6b5760405163f6202a8f60e01b81526001600160a01b0383166004820152602401610906565b600f54640100000000900460ff1615610acd57600e5481610a8b60025490565b610a959190611ea9565b1115610acd576040517f44ea8ea500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ad782826114bf565b5050565b610ae361116c565b600f54610100900460ff16610b0b57604051636cb5913960e01b815260040160405180910390fd5b610b15338261143a565b50565b60007f000000000000000000000000000000000000000000000000000000000000000015610b62576001600160a01b03821660009081526005602052604090205461087b90610953565b6001600160a01b03821660009081526020819052604090205461087b565b919050565b610b8d61116c565b610b95611508565b565b6060600480546107e490611e46565b3360008181526001602090815260408083206001600160a01b038716845290915281205490919083811015610c435760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610906565b610c5082868684036111c6565b506001949350505050565b610c6361116c565b600f5462010000900460ff16610ca5576040517f70a43fce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c610cb18282611f2c565b507f4456a0b562609d67398ddb488f136db285cd3c92343e0a7ba684925669237ade8160405161073c9190611c66565b600080610cee338461131e565b90506000610cfb84611361565b9050600081610d0a8487611e96565b610d149190611e96565b600f549091506301000000900460ff1615610d6a57600d5481610d3688610b18565b610d409190611ea9565b1115610d6a5760405163f6202a8f60e01b81526001600160a01b0387166004820152602401610906565b8215610d8857601054610d889033906001600160a01b031685611388565b8115610d9857610d98338361143a565b610da2868261151a565b9695505050505050565b600b805461075490611e46565b6000610dc460025490565b905090565b610dd161116c565b600f546601000000000000900460ff16610e17576040517fcd9e529800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081600954601254610e2a9190611ea9565b610e349190611ea9565b90506107d0811115610e5c57604051633e474e0d60e01b815260048101829052602401610906565b601282905560405182907fc1ff65ee907dc079b64ed9913d53f4bd593bd6ebd9b2a2708db2916d49e17ec390600090a25050565b610e9861116c565b600f5465010000000000900460ff16610edd576040517fc8a478a500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081600954601254610ef09190611ea9565b610efa9190611ea9565b90506107d0811115610f2257604051633e474e0d60e01b815260048101829052602401610906565b610f2b836110c9565b6010805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03851690811790915560118390556040518391907facc44e32fd5ca4240f6dbe6e8cf4eb49349c17c5ce5f80f1919a9c97b50d398a90600090a3505050565b610f9461116c565b610b15816110df565b610fa561116c565b600f54670100000000000000900460ff16610fd357604051630800e34b60e41b815260040160405180910390fd5b610fdc81611528565b60405181907f76e1296412dac7b50002658bf9aab02d0cfe366f373222d5c14d0168ee8199e390600090a250565b6001600160a01b0382166110605760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610906565b80600260008282546110729190611ea9565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b8060601b610b155763d92e233d6000526004601cfd5b6110e761116c565b6001600160a01b0381166111635760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610906565b610b158161156b565b600a546001600160a01b03163314610b955760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610906565b6001600160a01b0383166112415760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b0382166112bd5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b600060115460001415801561134157506010546001600160a01b03848116911614155b1561087b57612710601154836113579190611fec565b6109a79190611ebc565b6000601254600014610b80576127106012548361137e9190611fec565b61087b9190611ebc565b7f00000000000000000000000000000000000000000000000000000000000000001561142f57801561142a5760006113be61149c565b905060006113cc8284611fec565b90506113da858583846115ca565b836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161141f91815260200190565b60405180910390a350505b505050565b61142a8383836116ad565b7f00000000000000000000000000000000000000000000000000000000000000001561147957604051636cb5913960e01b815260040160405180910390fd5b610ad7828261189c565b600033611491858285611a05565b610c50858585611a91565b60008060006114a9611b0e565b90925090506114b88183611ebc565b9250505090565b7f0000000000000000000000000000000000000000000000000000000000000000156114fe57604051630732158d60e31b815260040160405180910390fd5b610ad7828261100a565b61151061116c565b610b95600061156b565b600033610875818585611a91565b7f000000000000000000000000000000000000000000000000000000000000000061156657604051630800e34b60e41b815260040160405180910390fd5b600955565b600a80546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b03841660009081526005602052604090205482811015611636576040517fe450d38c0000000000000000000000000000000000000000000000000000000081526001600160a01b03851660048201526024810182905260448101849052606401610906565b6001600160a01b03851660009081526005602052604090205461165a908490611e96565b6001600160a01b03808716600090815260056020526040808220939093559086168152205461168a908390611ea9565b6001600160a01b0390941660009081526005602052604090209390935550505050565b6001600160a01b0383166117295760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b0382166117a55760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b038316600090815260208190526040902054818110156118345760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35b50505050565b6001600160a01b0382166119185760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b038216600090815260208190526040902054818110156119a75760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146118965781811015611a845760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610906565b61189684848484036111c6565b7f00000000000000000000000000000000000000000000000000000000000000001561142f57611ac0836110c9565b611ac9826110c9565b80600003611b03576040517f76c4f5b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61142a838383611b24565b600080600754611b1c610db9565b915091509091565b6000611b2f82611bcb565b90506000611b3d8284611e96565b90506000806000611b4f868686611bde565b92509250925085600014611bc157611b69888885846115ca565b611b738286611c27565b866001600160a01b0316886001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef88604051611bb891815260200190565b60405180910390a35b5050505050505050565b60006127106009548361137e9190611fec565b600080600080611bec61149c565b90506000611bfa8289611fec565b90506000611c088389611fec565b90506000611c168489611fec565b929a91995091975095505050505050565b81600754611c359190611e96565b600755600854611c46908290611ea9565b6008555050565b600060208284031215611c5f57600080fd5b5035919050565b600060208083528351808285015260005b81811015611c9357858101830151858201604001528201611c77565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114610b8057600080fd5b60008060408385031215611cde57600080fd5b611ce783611cb4565b946020939093013593505050565b600080600060608486031215611d0a57600080fd5b611d1384611cb4565b9250611d2160208501611cb4565b9150604084013590509250925092565b600060208284031215611d4357600080fd5b6109a782611cb4565b634e487b7160e01b600052604160045260246000fd5b600060208284031215611d7457600080fd5b813567ffffffffffffffff80821115611d8c57600080fd5b818401915084601f830112611da057600080fd5b813581811115611db257611db2611d4c565b604051601f8201601f19908116603f01168101908382118183101715611dda57611dda611d4c565b81604052828152876020848701011115611df357600080fd5b826020860160208301376000928101602001929092525095945050505050565b60008060408385031215611e2657600080fd5b611e2f83611cb4565b9150611e3d60208401611cb4565b90509250929050565b600181811c90821680611e5a57607f821691505b602082108103611e7a57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561087b5761087b611e80565b8082018082111561087b5761087b611e80565b600082611ed957634e487b7160e01b600052601260045260246000fd5b500490565b601f82111561142a57600081815260208120601f850160051c81016020861015611f055750805b601f850160051c820191505b81811015611f2457828155600101611f11565b505050505050565b815167ffffffffffffffff811115611f4657611f46611d4c565b611f5a81611f548454611e46565b84611ede565b602080601f831160018114611f8f5760008415611f775750858301515b600019600386901b1c1916600185901b178555611f24565b600085815260208120601f198616915b82811015611fbe57888601518255948401946001909101908401611f9f565b5085821015611fdc5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b808202811582820484141761087b5761087b611e8056fea2646970667358221220f0883b06564851f25c2214f07da7f7c972f341f687d3de12c8903d945027bfe064736f6c63430008110033","sourceMap":"395:14391:5:-:0;;;3119:2064;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3470:5;3483:7;3498:10;3516:18;3542:13;3563:18;3585:1;3563:23;:42;;3604:1;3563:42;;;3589:12;;;;3563:42;3613:31;;;;1747:5:6;1754:7;2046:5:1;:13;1747:5:6;2046::1;:13;:::i;:::-;-1:-1:-1;2069:7:1;:17;2079:7;2069;:17;:::i;:::-;;1980:113;;1773:12:6::1;1789:1;1773:17;1769:161;;1800:59;1812:10:::0;1839:19:::1;1845:13:::0;1839:2:::1;:19;:::i;:::-;1824:34;::::0;:12;:34:::1;:::i;:::-;1800:11;;;;;:59;;:::i;:::-;1894:27;1909:12:::0;-1:-1:-1;;1894:27:6::1;:::i;:::-;1878:44;::::0;-1:-1:-1;;1878:44:6::1;:::i;:::-;1867:7;:56:::0;1769:161:::1;1958:7;::::0;-1:-1:-1;;;;;1936:19:6;;::::1;;::::0;;;:7:::1;:19;::::0;;;;:29;;;;1971:7:::1;:18:::0;-1:-1:-1;;1995:28:6::1;;;::::0;-1:-1:-1;936:32:0;;-1:-1:-1;955:12:0;734:10:4;;655:96;955:12:0;936:18;:32::i;:::-;3836:17:5::1;:31;;;:164;;;;;3880:17;:29;;;:72;;;-1:-1:-1::0;3923:29:5;;3880:72:::1;:119;;;;3966:17;:33;;;3880:119;3835:231;;;;4013:17;:31;;;4012:32;:53;;;;-1:-1:-1::0;4048:12:5;;::::1;::::0;:17;::::1;4012:53;3824:296;;;4088:25;;-1:-1:-1::0;;;4088:25:5::1;;;;;;;;;;;3824:296;4130:17;:41;;;4126:151;;;4185:15:::0;;4198:1:::1;4185:20:::0;4181:90:::1;;4246:15:::0;;4224:38:::1;::::0;-1:-1:-1;;;4224:38:5;;::::1;::::0;::::1;10344:25:8::0;;;;10317:18;;4224:38:5::1;;;;;;;;4181:90;4302:2;4286:13;:18;;;4282:76;;;4321:30;::::0;-1:-1:-1;;;4321:30:5;;10552:4:8;10540:17;;4321:30:5::1;::::0;::::1;10522:36:8::0;10495:18;;4321:30:5::1;10380:184:8::0;4282:76:5::1;4375:17;:33;;;:112;;;;-1:-1:-1::0;4420:29:5;;4419:30:::1;::::0;:67:::1;;-1:-1:-1::0;4470:15:5::1;::::0;::::1;::::0;3342:12:1;;4454:31:5::1;4419:67;4364:176;;;4509:24;;-1:-1:-1::0;;;4509:24:5::1;;;;;;;;;;;4364:176;4546:56;4560:17:::0;4579:9;4590:11;4546:13:::1;:56::i;:::-;4609:37;4635:10;4609:25;;;;;:37;;:::i;:::-;4653:10;:24:::0;;-1:-1:-1;;;;;;4653:24:5::1;-1:-1:-1::0;;;;;4653:24:5;::::1;;::::0;;4693:12;;4684:6:::1;:21:::0;4693:12:::1;4726::::0;::::1;::::0;4711::::1;:27:::0;4744:34:::1;::::0;;;4818:15;;4784:49:::1;::::0;4839:18:::1;:35;4860:14:::0;4839:18;:35:::1;:::i;:::-;-1:-1:-1::0;;;;;;4880:30:5;::::1;;::::0;;;4916:25:::1;::::0;::::1;;::::0;;;4947:31;;:11:::1;:31:::0;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;;::::1;::::0;-1:-1:-1;;4947:31:5;;;;::::1;;-1:-1:-1::0;;4947:31:5;;;;;;::::1;;::::0;;::::1;::::0;;;::::1;-1:-1:-1::0;;4947:31:5;;;::::1;;::::0;;;::::1;-1:-1:-1::0;;4947:31:5;;;;::::1;;::::0;;;::::1;;-1:-1:-1::0;;;;4947:31:5;;;::::1;;::::0;;;::::1;-1:-1:-1::0;;;;4947:31:5;;;;;;;::::1;;::::0;;;::::1;::::0;;;::::1;-1:-1:-1::0;;;;4947:31:5;;;::::1;;::::0;;;::::1;-1:-1:-1::0;;;;4947:31:5;;;;;;;::::1;;::::0;;;::::1;;::::0;;4984:11:::1;:28;4998:14:::0;4984:11;:28:::1;:::i;:::-;-1:-1:-1::0;5045:15:5;;5018:24:::1;:42:::0;5045:15:::1;5083::::0;::::1;::::0;5066:14:::1;:32:::0;5123:10:::1;-1:-1:-1::0;;;;;5109:24:5;::::1;;5105:74;;5143:29;5161:10:::0;5143:17:::1;:29::i;:::-;3119:2064:::0;;;;;;;;;;395:14391;;8520:535:1;-1:-1:-1;;;;;8603:21:1;;8595:65;;;;-1:-1:-1;;;8595:65:1;;10771:2:8;8595:65:1;;;10753:21:8;10810:2;10790:18;;;10783:30;10849:33;10829:18;;;10822:61;10900:18;;8595:65:1;10569:355:8;8595:65:1;8747:6;8731:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;8899:18:1;;:9;:18;;;;;;;;;;;:28;;;;;;8952:37;10344:25:8;;;8952:37:1;;10317:18:8;8952:37:1;;;;;;;8520:535;;:::o;2426:187:0:-;2518:6;;;-1:-1:-1;;;;;2534:17:0;;;-1:-1:-1;;;;;;2534:17:0;;;;;;;2566:40;;2518:6;;;2534:17;2518:6;;2566:40;;2499:16;;2566:40;2489:124;2426:187;:::o;5187:549:5:-;5338:16;5368:17;:28;;;5364:120;;;5406:38;5432:11;5406:25;;;;;:38;;:::i;:::-;5465:12;;5453:24;;;;:::i;:::-;;;5364:120;5493:17;:33;;;5489:78;;;5548:12;;;;5536:24;;;;:::i;:::-;;;5489:78;5576:17;:31;;;5572:76;;;5629:12;;;;5617:24;;;;:::i;:::-;;;5572:76;558:5;5657:8;:26;5653:79;;;5700:25;;-1:-1:-1;;;5700:25:5;;;;;10344::8;;;10317:18;;5700:25:5;10198:177:8;5653:79:5;5332:404;5187:549;;;:::o;1674:396:7:-;1820:4;1816:2;1812:13;1802:258;;1975:10;1969:4;1962:24;2047:4;2041;2034:18;1802:258;1674:396;:::o;13768:115:5:-;1094:13:0;:11;:13::i;:::-;13845:33:5::1;13869:8;13845:23;;;;;:33;;:::i;12073:91:1:-:0;;;;:::o;1359:130:0:-;1273:6;;-1:-1:-1;;;;;1273:6:0;734:10:4;1422:23:0;1414:68;;;;-1:-1:-1;;;1414:68:0;;11261:2:8;1414:68:0;;;11243:21:8;;;11280:18;;;11273:30;11339:34;11319:18;;;11312:62;11391:18;;1414:68:0;11059:356:8;1414:68:0;1359:130::o;2074:198::-;1094:13;:11;:13::i;:::-;-1:-1:-1;;;;;2162:22:0;::::1;2154:73;;;::::0;-1:-1:-1;;;2154:73:0;;11622:2:8;2154:73:0::1;::::0;::::1;11604:21:8::0;11661:2;11641:18;;;11634:30;11700:34;11680:18;;;11673:62;-1:-1:-1;;;11751:18:8;;;11744:36;11797:19;;2154:73:0::1;11420:402:8::0;2154:73:0::1;2237:28;2256:8:::0;2237:18:::1;:28::i;14:127:8:-:0;75:10;70:3;66:20;63:1;56:31;106:4;103:1;96:15;130:4;127:1;120:15;146:275;217:2;211:9;282:2;263:13;;-1:-1:-1;;259:27:8;247:40;;-1:-1:-1;;;;;302:34:8;;338:22;;;299:62;296:88;;;364:18;;:::i;:::-;400:2;393:22;146:275;;-1:-1:-1;146:275:8:o;426:650::-;480:5;533:3;526:4;518:6;514:17;510:27;500:55;;551:1;548;541:12;500:55;574:13;;-1:-1:-1;;;;;599:26:8;;596:52;;;628:18;;:::i;:::-;667:4;695:53;738:2;719:13;;-1:-1:-1;;715:27:8;711:36;;695:53;:::i;:::-;773:2;764:7;757:19;817:3;812:2;807;799:6;795:15;791:24;788:33;785:53;;;834:1;831;824:12;785:53;856:1;866:134;880:2;877:1;874:9;866:134;;;969:14;;;965:23;;959:30;937:15;;;933:24;;926:64;891:10;;866:134;;;-1:-1:-1;1043:1:8;1020:16;;;1016:25;;;1009:36;;;;1024:7;426:650;-1:-1:-1;;;426:650:8:o;1081:160::-;1158:13;;1211:4;1200:16;;1190:27;;1180:55;;1231:1;1228;1221:12;1180:55;1081:160;;;:::o;1246:177::-;1325:13;;-1:-1:-1;;;;;1367:31:8;;1357:42;;1347:70;;1413:1;1410;1403:12;1428:164;1504:13;;1553;;1546:21;1536:32;;1526:60;;1582:1;1579;1572:12;1597:1029;1671:5;1701:6;1744:2;1732:9;1727:3;1723:19;1719:28;1716:48;;;1760:1;1757;1750:12;1716:48;1793:2;1787:9;1823:15;;;;-1:-1:-1;;;;;1853:34:8;;1889:22;;;1850:62;1847:88;;;1915:18;;:::i;:::-;1955:10;1951:2;1944:22;1984:6;1975:15;;2014:37;2041:9;2014:37;:::i;:::-;2006:6;1999:53;2085:46;2127:2;2116:9;2112:18;2085:46;:::i;:::-;2080:2;2072:6;2068:15;2061:71;2165:46;2207:2;2196:9;2192:18;2165:46;:::i;:::-;2160:2;2152:6;2148:15;2141:71;2245:46;2287:2;2276:9;2272:18;2245:46;:::i;:::-;2240:2;2232:6;2228:15;2221:71;2326:47;2368:3;2357:9;2353:19;2326:47;:::i;:::-;2320:3;2312:6;2308:16;2301:73;2408:47;2450:3;2439:9;2435:19;2408:47;:::i;:::-;2402:3;2394:6;2390:16;2383:73;2490:47;2532:3;2521:9;2517:19;2490:47;:::i;:::-;2484:3;2476:6;2472:16;2465:73;2572:47;2614:3;2603:9;2599:19;2572:47;:::i;:::-;2566:3;2558:6;2554:16;2547:73;;;1597:1029;;;;:::o;2631:661::-;2703:5;2756:3;2749:4;2741:6;2737:17;2733:27;2723:55;;2774:1;2771;2764:12;2723:55;2807:2;2801:9;2849:2;2837:15;;-1:-1:-1;;;;;2867:34:8;;2903:22;;;2864:62;2861:88;;;2929:18;;:::i;:::-;2965:2;2958:22;3000:6;3041:2;3029:15;;3056;;;3053:35;;;3084:1;3081;3074:12;3053:35;3108:6;3123:139;3139:6;3134:3;3131:15;3123:139;;;3207:10;;3195:23;;3247:4;3238:14;;;;3156;3123:139;;;-1:-1:-1;3280:6:8;;2631:661;-1:-1:-1;;;;;2631:661:8:o;3297:650::-;3358:5;3411:3;3404:4;3396:6;3392:17;3388:27;3378:55;;3429:1;3426;3419:12;3378:55;3462:2;3456:9;;;3492:15;;-1:-1:-1;;;;;3522:34:8;;3558:22;;;3519:62;3516:88;;;3584:18;;:::i;:::-;3624:10;3620:2;3613:22;;3655:6;3696:2;3688:6;3684:15;3722:3;3714:6;3711:15;3708:35;;;3739:1;3736;3729:12;3952:1485;4210:6;4218;4226;4234;4242;4250;4258;4266;4274;4282;4335:3;4323:9;4314:7;4310:23;4306:33;4303:53;;;4352:1;4349;4342:12;4303:53;4379:16;;-1:-1:-1;;;;;4444:14:8;;;4441:34;;;4471:1;4468;4461:12;4441:34;4494:61;4547:7;4538:6;4527:9;4523:22;4494:61;:::i;:::-;4484:71;;4601:2;4590:9;4586:18;4580:25;4564:41;;4630:2;4620:8;4617:16;4614:36;;;4646:1;4643;4636:12;4614:36;4669:63;4724:7;4713:8;4702:9;4698:24;4669:63;:::i;:::-;4659:73;;4772:2;4761:9;4757:18;4751:25;4741:35;;4795:47;4838:2;4827:9;4823:18;4795:47;:::i;:::-;4785:57;;4861:50;4906:3;4895:9;4891:19;4861:50;:::i;:::-;4851:60;;4930:75;4997:7;4991:3;4980:9;4976:19;4930:75;:::i;:::-;4920:85;;5051:3;5040:9;5036:19;5030:26;5014:42;;5081:2;5071:8;5068:16;5065:36;;;5097:1;5094;5087:12;5065:36;;5120:63;5175:7;5164:8;5153:9;5149:24;5120:63;:::i;:::-;5110:73;;;5202:50;5247:3;5236:9;5232:19;5202:50;:::i;:::-;5192:60;;5271:76;5339:7;5333:3;5322:9;5318:19;5271:76;:::i;:::-;5261:86;;5366:65;5423:7;5417:3;5406:9;5402:19;5366:65;:::i;:::-;5356:75;;3952:1485;;;;;;;;;;;;;:::o;5574:380::-;5653:1;5649:12;;;;5696;;;5717:61;;5771:4;5763:6;5759:17;5749:27;;5717:61;5824:2;5816:6;5813:14;5793:18;5790:38;5787:161;;5870:10;5865:3;5861:20;5858:1;5851:31;5905:4;5902:1;5895:15;5933:4;5930:1;5923:15;5787:161;;5574:380;;;:::o;6085:545::-;6187:2;6182:3;6179:11;6176:448;;;6223:1;6248:5;6244:2;6237:17;6293:4;6289:2;6279:19;6363:2;6351:10;6347:19;6344:1;6340:27;6334:4;6330:38;6399:4;6387:10;6384:20;6381:47;;;-1:-1:-1;6422:4:8;6381:47;6477:2;6472:3;6468:12;6465:1;6461:20;6455:4;6451:31;6441:41;;6532:82;6550:2;6543:5;6540:13;6532:82;;;6595:17;;;6576:1;6565:13;6532:82;;;6536:3;;;6085:545;;;:::o;6806:1352::-;6926:10;;-1:-1:-1;;;;;6948:30:8;;6945:56;;;6981:18;;:::i;:::-;7010:97;7100:6;7060:38;7092:4;7086:11;7060:38;:::i;:::-;7054:4;7010:97;:::i;:::-;7162:4;;7226:2;7215:14;;7243:1;7238:663;;;;7945:1;7962:6;7959:89;;;-1:-1:-1;8014:19:8;;;8008:26;7959:89;-1:-1:-1;;6763:1:8;6759:11;;;6755:24;6751:29;6741:40;6787:1;6783:11;;;6738:57;8061:81;;7208:944;;7238:663;6032:1;6025:14;;;6069:4;6056:18;;-1:-1:-1;;7274:20:8;;;7392:236;7406:7;7403:1;7400:14;7392:236;;;7495:19;;;7489:26;7474:42;;7587:27;;;;7555:1;7543:14;;;;7422:19;;7392:236;;;7396:3;7656:6;7647:7;7644:19;7641:201;;;7717:19;;;7711:26;-1:-1:-1;;7800:1:8;7796:14;;;7812:3;7792:24;7788:37;7784:42;7769:58;7754:74;;7641:201;-1:-1:-1;;;;;7888:1:8;7872:14;;;7868:22;7855:36;;-1:-1:-1;6806:1352:8:o;8163:127::-;8224:10;8219:3;8215:20;8212:1;8205:31;8255:4;8252:1;8245:15;8279:4;8276:1;8269:15;8295:422;8384:1;8427:5;8384:1;8441:270;8462:7;8452:8;8449:21;8441:270;;;8521:4;8517:1;8513:6;8509:17;8503:4;8500:27;8497:53;;;8530:18;;:::i;:::-;8580:7;8570:8;8566:22;8563:55;;;8600:16;;;;8563:55;8679:22;;;;8639:15;;;;8441:270;;;8445:3;8295:422;;;;;:::o;8722:806::-;8771:5;8801:8;8791:80;;-1:-1:-1;8842:1:8;8856:5;;8791:80;8890:4;8880:76;;-1:-1:-1;8927:1:8;8941:5;;8880:76;8972:4;8990:1;8985:59;;;;9058:1;9053:130;;;;8965:218;;8985:59;9015:1;9006:10;;9029:5;;;9053:130;9090:3;9080:8;9077:17;9074:43;;;9097:18;;:::i;:::-;-1:-1:-1;;9153:1:8;9139:16;;9168:5;;8965:218;;9267:2;9257:8;9254:16;9248:3;9242:4;9239:13;9235:36;9229:2;9219:8;9216:16;9211:2;9205:4;9202:12;9198:35;9195:77;9192:159;;;-1:-1:-1;9304:19:8;;;9336:5;;9192:159;9383:34;9408:8;9402:4;9383:34;:::i;:::-;9453:6;9449:1;9445:6;9441:19;9432:7;9429:32;9426:58;;;9464:18;;:::i;:::-;9502:20;;-1:-1:-1;8722:806:8;;;;;:::o;9533:140::-;9591:5;9620:47;9661:4;9651:8;9647:19;9641:4;9620:47;:::i;:::-;9611:56;9533:140;-1:-1:-1;;;9533:140:8:o;9678:168::-;9751:9;;;9782;;9799:15;;;9793:22;;9779:37;9769:71;;9820:18;;:::i;9851:209::-;9883:1;9909;9899:132;;9953:10;9948:3;9944:20;9941:1;9934:31;9988:4;9985:1;9978:15;10016:4;10013:1;10006:15;9899:132;-1:-1:-1;10045:9:8;;9851:209::o;10065:128::-;10132:9;;;10153:11;;;10150:37;;;10167:18;;:::i;10929:125::-;10994:9;;;11015:10;;;11012:36;;;11028:18;;:::i;11420:402::-;395:14391:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"608060405234801561001057600080fd5b50600436106102e95760003560e01c8063883356d911610191578063af465a27116100e3578063de0060ca11610097578063f820f56711610071578063f820f56714610625578063f91f825d14610636578063ffa1ad741461064957600080fd5b8063de0060ca146105ec578063f19c4e3b146105ff578063f2fde38b1461061257600080fd5b8063d48e4127116100c8578063d48e412714610597578063d8f67851146105a0578063dd62ed3e146105b357600080fd5b8063af465a271461057c578063b7bda68f1461058457600080fd5b80639703a19d11610145578063a476df611161011f578063a476df611461054e578063a9059cbb14610561578063a9d866851461057457600080fd5b80639703a19d1461050b578063a32f697614610514578063a457c2d71461053b57600080fd5b80638dac7191116101765780638dac7191146104c75780638e8c10a2146104ee57806395d89b411461050357600080fd5b8063883356d9146104925780638da5cb5b146104a257600080fd5b8063313ce5671161024a57806346b45af7116101fe5780635a3990ce116101d85780635a3990ce1461046557806370a0823114610477578063715018a61461048a57600080fd5b806346b45af71461043d5780634ac0bc3214610448578063542e96671461045c57600080fd5b8063395093511161022f578063395093511461040457806340c10f191461041757806342966c681461042a57600080fd5b8063313ce567146103ac578063378dc3dc146103dd57600080fd5b806323b872dd116102a15780632d838119116102865780632d8381191461037a5780632e0ee48e1461038d5780632fa782eb146103a357600080fd5b806323b872dd1461035e5780632ab4d0521461037157600080fd5b806306fdde03116102d257806306fdde0314610321578063095ea7b31461032957806318160ddd1461034c57600080fd5b806302252c4d146102ee578063044ab74e14610303575b600080fd5b6103016102fc366004611c4d565b610685565b005b61030b610747565b6040516103189190611c66565b60405180910390f35b61030b6107d5565b61033c610337366004611ccb565b610867565b6040519015158152602001610318565b6002545b604051908152602001610318565b61033c61036c366004611cf5565b610881565b610350600e5481565b610350610388366004611c4d565b610953565b600f54670100000000000000900460ff1661033c565b61035060115481565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610318565b6103507f000000000000000000000000000000000000000000000000000000000000000081565b61033c610412366004611ccb565b6109ae565b610301610425366004611ccb565b6109ed565b610301610438366004611c4d565b610adb565b600f5460ff1661033c565b600f5465010000000000900460ff1661033c565b61035060125481565b600f546301000000900460ff1661033c565b610350610485366004611d31565b610b18565b610301610b85565b600f54610100900460ff1661033c565b600a546001600160a01b03165b6040516001600160a01b039091168152602001610318565b6104af7f000000000000000000000000000000000000000000000000000000000000000081565b600f546601000000000000900460ff1661033c565b61030b610b97565b61035060095481565b6103507f000000000000000000000000000000000000000000000000000000000000000081565b61033c610549366004611ccb565b610ba6565b61030161055c366004611d62565b610c5b565b61033c61056f366004611ccb565b610ce1565b61030b610dac565b610350610db9565b6010546104af906001600160a01b031681565b610350600d5481565b6103016105ae366004611c4d565b610dc9565b6103506105c1366004611e13565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b600f54640100000000900460ff1661033c565b61030161060d366004611ccb565b610e90565b610301610620366004611d31565b610f8c565b600f5462010000900460ff1661033c565b610301610644366004611c4d565b610f9d565b61030b6040518060400160405280600881526020017f646566695f765f3300000000000000000000000000000000000000000000000081525081565b61068d61116c565b600f546301000000900460ff166106d0576040517f6273340f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d54811161070b576040517fa43d2d7600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d8190556040518181527f2905481c6fd1a037492016c4760435a52203d82a6f34dc3de40f464c1bf42d59906020015b60405180910390a150565b600c805461075490611e46565b80601f016020809104026020016040519081016040528092919081815260200182805461078090611e46565b80156107cd5780601f106107a2576101008083540402835291602001916107cd565b820191906000526020600020905b8154815290600101906020018083116107b057829003601f168201915b505050505081565b6060600380546107e490611e46565b80601f016020809104026020016040519081016040528092919081815260200182805461081090611e46565b801561085d5780601f106108325761010080835404028352916020019161085d565b820191906000526020600020905b81548152906001019060200180831161084057829003601f168201915b5050505050905090565b6000336108758185856111c6565b60019150505b92915050565b60008061088e858461131e565b9050600061089b84611361565b90506000816108aa8487611e96565b6108b49190611e96565b600f549091506301000000900460ff161561090f57600d54816108d688610b18565b6108e09190611ea9565b111561090f5760405163f6202a8f60e01b81526001600160a01b03871660048201526024015b60405180910390fd5b821561092d5760105461092d9088906001600160a01b031685611388565b811561093d5761093d878361143a565b610948878783611483565b979650505050505050565b6000600754821115610991576040517fc91fa8bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061099b61149c565b90506109a78184611ebc565b9392505050565b3360008181526001602090815260408083206001600160a01b038716845290915281205490919061087590829086906109e8908790611ea9565b6111c6565b6109f561116c565b600f5460ff16610a1857604051630732158d60e31b815260040160405180910390fd5b600f546301000000900460ff1615610a6b57600d5481610a3784610b18565b610a419190611ea9565b1115610a6b5760405163f6202a8f60e01b81526001600160a01b0383166004820152602401610906565b600f54640100000000900460ff1615610acd57600e5481610a8b60025490565b610a959190611ea9565b1115610acd576040517f44ea8ea500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ad782826114bf565b5050565b610ae361116c565b600f54610100900460ff16610b0b57604051636cb5913960e01b815260040160405180910390fd5b610b15338261143a565b50565b60007f000000000000000000000000000000000000000000000000000000000000000015610b62576001600160a01b03821660009081526005602052604090205461087b90610953565b6001600160a01b03821660009081526020819052604090205461087b565b919050565b610b8d61116c565b610b95611508565b565b6060600480546107e490611e46565b3360008181526001602090815260408083206001600160a01b038716845290915281205490919083811015610c435760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610906565b610c5082868684036111c6565b506001949350505050565b610c6361116c565b600f5462010000900460ff16610ca5576040517f70a43fce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c610cb18282611f2c565b507f4456a0b562609d67398ddb488f136db285cd3c92343e0a7ba684925669237ade8160405161073c9190611c66565b600080610cee338461131e565b90506000610cfb84611361565b9050600081610d0a8487611e96565b610d149190611e96565b600f549091506301000000900460ff1615610d6a57600d5481610d3688610b18565b610d409190611ea9565b1115610d6a5760405163f6202a8f60e01b81526001600160a01b0387166004820152602401610906565b8215610d8857601054610d889033906001600160a01b031685611388565b8115610d9857610d98338361143a565b610da2868261151a565b9695505050505050565b600b805461075490611e46565b6000610dc460025490565b905090565b610dd161116c565b600f546601000000000000900460ff16610e17576040517fcd9e529800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081600954601254610e2a9190611ea9565b610e349190611ea9565b90506107d0811115610e5c57604051633e474e0d60e01b815260048101829052602401610906565b601282905560405182907fc1ff65ee907dc079b64ed9913d53f4bd593bd6ebd9b2a2708db2916d49e17ec390600090a25050565b610e9861116c565b600f5465010000000000900460ff16610edd576040517fc8a478a500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081600954601254610ef09190611ea9565b610efa9190611ea9565b90506107d0811115610f2257604051633e474e0d60e01b815260048101829052602401610906565b610f2b836110c9565b6010805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03851690811790915560118390556040518391907facc44e32fd5ca4240f6dbe6e8cf4eb49349c17c5ce5f80f1919a9c97b50d398a90600090a3505050565b610f9461116c565b610b15816110df565b610fa561116c565b600f54670100000000000000900460ff16610fd357604051630800e34b60e41b815260040160405180910390fd5b610fdc81611528565b60405181907f76e1296412dac7b50002658bf9aab02d0cfe366f373222d5c14d0168ee8199e390600090a250565b6001600160a01b0382166110605760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610906565b80600260008282546110729190611ea9565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b8060601b610b155763d92e233d6000526004601cfd5b6110e761116c565b6001600160a01b0381166111635760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610906565b610b158161156b565b600a546001600160a01b03163314610b955760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610906565b6001600160a01b0383166112415760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b0382166112bd5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b600060115460001415801561134157506010546001600160a01b03848116911614155b1561087b57612710601154836113579190611fec565b6109a79190611ebc565b6000601254600014610b80576127106012548361137e9190611fec565b61087b9190611ebc565b7f00000000000000000000000000000000000000000000000000000000000000001561142f57801561142a5760006113be61149c565b905060006113cc8284611fec565b90506113da858583846115ca565b836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161141f91815260200190565b60405180910390a350505b505050565b61142a8383836116ad565b7f00000000000000000000000000000000000000000000000000000000000000001561147957604051636cb5913960e01b815260040160405180910390fd5b610ad7828261189c565b600033611491858285611a05565b610c50858585611a91565b60008060006114a9611b0e565b90925090506114b88183611ebc565b9250505090565b7f0000000000000000000000000000000000000000000000000000000000000000156114fe57604051630732158d60e31b815260040160405180910390fd5b610ad7828261100a565b61151061116c565b610b95600061156b565b600033610875818585611a91565b7f000000000000000000000000000000000000000000000000000000000000000061156657604051630800e34b60e41b815260040160405180910390fd5b600955565b600a80546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b03841660009081526005602052604090205482811015611636576040517fe450d38c0000000000000000000000000000000000000000000000000000000081526001600160a01b03851660048201526024810182905260448101849052606401610906565b6001600160a01b03851660009081526005602052604090205461165a908490611e96565b6001600160a01b03808716600090815260056020526040808220939093559086168152205461168a908390611ea9565b6001600160a01b0390941660009081526005602052604090209390935550505050565b6001600160a01b0383166117295760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b0382166117a55760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b038316600090815260208190526040902054818110156118345760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35b50505050565b6001600160a01b0382166119185760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b038216600090815260208190526040902054818110156119a75760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610906565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146118965781811015611a845760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610906565b61189684848484036111c6565b7f00000000000000000000000000000000000000000000000000000000000000001561142f57611ac0836110c9565b611ac9826110c9565b80600003611b03576040517f76c4f5b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61142a838383611b24565b600080600754611b1c610db9565b915091509091565b6000611b2f82611bcb565b90506000611b3d8284611e96565b90506000806000611b4f868686611bde565b92509250925085600014611bc157611b69888885846115ca565b611b738286611c27565b866001600160a01b0316886001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef88604051611bb891815260200190565b60405180910390a35b5050505050505050565b60006127106009548361137e9190611fec565b600080600080611bec61149c565b90506000611bfa8289611fec565b90506000611c088389611fec565b90506000611c168489611fec565b929a91995091975095505050505050565b81600754611c359190611e96565b600755600854611c46908290611ea9565b6008555050565b600060208284031215611c5f57600080fd5b5035919050565b600060208083528351808285015260005b81811015611c9357858101830151858201604001528201611c77565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114610b8057600080fd5b60008060408385031215611cde57600080fd5b611ce783611cb4565b946020939093013593505050565b600080600060608486031215611d0a57600080fd5b611d1384611cb4565b9250611d2160208501611cb4565b9150604084013590509250925092565b600060208284031215611d4357600080fd5b6109a782611cb4565b634e487b7160e01b600052604160045260246000fd5b600060208284031215611d7457600080fd5b813567ffffffffffffffff80821115611d8c57600080fd5b818401915084601f830112611da057600080fd5b813581811115611db257611db2611d4c565b604051601f8201601f19908116603f01168101908382118183101715611dda57611dda611d4c565b81604052828152876020848701011115611df357600080fd5b826020860160208301376000928101602001929092525095945050505050565b60008060408385031215611e2657600080fd5b611e2f83611cb4565b9150611e3d60208401611cb4565b90509250929050565b600181811c90821680611e5a57607f821691505b602082108103611e7a57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561087b5761087b611e80565b8082018082111561087b5761087b611e80565b600082611ed957634e487b7160e01b600052601260045260246000fd5b500490565b601f82111561142a57600081815260208120601f850160051c81016020861015611f055750805b601f850160051c820191505b81811015611f2457828155600101611f11565b505050505050565b815167ffffffffffffffff811115611f4657611f46611d4c565b611f5a81611f548454611e46565b84611ede565b602080601f831160018114611f8f5760008415611f775750858301515b600019600386901b1c1916600185901b178555611f24565b600085815260208120601f198616915b82811015611fbe57888601518255948401946001909101908401611f9f565b5085821015611fdc5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b808202811582820484141761087b5761087b611e8056fea2646970667358221220f0883b06564851f25c2214f07da7f7c972f341f687d3de12c8903d945027bfe064736f6c63430008110033","sourceMap":"395:14391:5:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8278:392;;;;;;:::i;:::-;;:::i;:::-;;672:25;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2158:98:1;;;:::i;4444:197::-;;;;;;:::i;:::-;;:::i;:::-;;;1377:14:8;;1370:22;1352:41;;1340:2;1325:18;4444:197:1;1212:187:8;3255:106:1;3342:12;;3255:106;;;1550:25:8;;;1538:2;1523:18;3255:106:1;1404:177:8;11602:700:5;;;;;;:::i;:::-;;:::i;846:29::-;;;;;;5254:229:6;;;;;;:::i;:::-;;:::i;7622:94:5:-;7686:11;:25;;;;;;7622:94;;1328:21;;;;;;6972:92;;;2091:4:8;7050:9:5;2079:17:8;2061:36;;2049:2;2034:18;6972:92:5;1919:184:8;701:38:5;;;;;5854:234:1;;;;;;:::i;:::-;;:::i;12533:471:5:-;;;;;;:::i;:::-;;:::i;13188:150::-;;;;;;:::i;:::-;;:::i;5868:90::-;5930:11;:23;;;5868:90;;7174:88;7235:11;:22;;;;;;7174:88;;1353:27;;;;;;6296:114;6370:11;:35;;;;;;6296:114;;2199:214:6;;;;;;:::i;:::-;;:::i;13504:91:5:-;;;:::i;6054:90::-;6116:11;:23;;;;;;6054:90;;1201:85:0;1273:6;;-1:-1:-1;;;;;1273:6:0;1201:85;;;-1:-1:-1;;;;;2463:55:8;;;2445:74;;2433:2;2418:18;1201:85:0;2299:226:8;1216:42:5;;;;;7383:98;7449:11;:27;;;;;;7383:98;;2369:102:1;;;:::i;673:22:6:-;;;;;;743:56:5;;;;;6575:427:1;;;;;;:::i;:::-;;:::i;7860:232:5:-;;;;;;:::i;:::-;;:::i;10534:685::-;;;;;;:::i;:::-;;:::i;636:32::-;;;:::i;1104:88:6:-;;;:::i;1299:25:5:-;;;;;-1:-1:-1;;;;;1299:25:5;;;803:39;;;;;;9859:374;;;;;;:::i;:::-;;:::i;3987:149:1:-;;;;;;:::i;:::-;-1:-1:-1;;;;;4102:18:1;;;4076:7;4102:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;3987:149;6544:98:5;6610:11;:27;;;;;;6544:98;;9249:443;;;;;;:::i;:::-;;:::i;13768:115::-;;;;;;:::i;:::-;;:::i;6760:107::-;6832:11;:30;;;;;;6760:107;;8822:218;;;;;;:::i;:::-;;:::i;567:43::-;;;;;;;;;;;;;;;;;;;;;8278:392;1094:13:0;:11;:13::i;:::-;6370:11:5;:35;;;;;;8375:79:::1;;8421:26;;;;;;;;;;;;;;8375:79;8484:24;;8463:17;:45;8459:106;;8525:33;;;;;;;;;;;;;;8459:106;8571:24;:44:::0;;;8626:39:::1;::::0;1550:25:8;;;8626:39:5::1;::::0;1538:2:8;1523:18;8626:39:5::1;;;;;;;;8278:392:::0;:::o;672:25::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;2158:98:1:-;2212:13;2244:5;2237:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2158:98;:::o;4444:197::-;4527:4;734:10:4;4581:32:1;734:10:4;4597:7:1;4606:6;4581:8;:32::i;:::-;4630:4;4623:11;;;4444:197;;;;;:::o;11602:700:5:-;11715:4;11727:17;11747:24;11758:4;11764:6;11747:10;:24::i;:::-;11727:44;;11777:23;11803:24;11820:6;11803:16;:24::i;:::-;11777:50;-1:-1:-1;11833:24:5;11777:50;11860:18;11869:9;11860:6;:18;:::i;:::-;:36;;;;:::i;:::-;6370:11;:35;11833:63;;-1:-1:-1;6370:35:5;;;;;11903:167;;;11980:24;;11961:16;11945:13;11955:2;11945:9;:13::i;:::-;:32;;;;:::i;:::-;:59;11941:123;;;12023:32;;-1:-1:-1;;;12023:32:5;;-1:-1:-1;;;;;2463:55:8;;12023:32:5;;;2445:74:8;2418:18;;12023:32:5;;;;;;;;11941:123;12080:14;;12076:88;;12135:10;;12104:53;;12129:4;;-1:-1:-1;;;;;12135:10:5;12147:9;12104:24;:53::i;:::-;12173:20;;12169:69;;12203:28;12209:4;12215:15;12203:5;:28::i;:::-;12251:46;12270:4;12276:2;12280:16;12251:18;:46::i;:::-;12244:53;11602:700;-1:-1:-1;;;;;;;11602:700:5:o;5254:229:6:-;5321:7;5350;;5340;:17;5336:70;;;5374:25;;;;;;;;;;;;;;5336:70;5412:19;5434:10;:8;:10::i;:::-;5412:32;-1:-1:-1;5457:21:6;5412:32;5457:7;:21;:::i;:::-;5450:28;5254:229;-1:-1:-1;;;5254:229:6:o;5854:234:1:-;734:10:4;5942:4:1;4102:18;;;:11;:18;;;;;;;;-1:-1:-1;;;;;4102:27:1;;;;;;;;;;5942:4;;734:10:4;5996:64:1;;734:10:4;;4102:27:1;;6021:38;;6049:10;;6021:38;:::i;:::-;5996:8;:64::i;12533:471:5:-;1094:13:0;:11;:13::i;:::-;5930:11:5;:23;;;12600:60:::1;;12634:19;;-1:-1:-1::0;;;12634:19:5::1;;;;;;;;;;;12600:60;6370:11:::0;:35;;;;;;12665:157:::1;;;12732:24;;12723:6;12707:13;12717:2;12707:9;:13::i;:::-;:22;;;;:::i;:::-;:49;12703:113;;;12775:32;::::0;-1:-1:-1;;;12775:32:5;;-1:-1:-1;;;;;2463:55:8;;12775:32:5::1;::::0;::::1;2445:74:8::0;2418:18;;12775:32:5::1;2299:226:8::0;12703:113:5::1;6610:11:::0;:27;;;;;;12827:143:::1;;;12886:14;;12877:6;12861:13;3342:12:1::0;;;3255:106;12861:13:5::1;:22;;;;:::i;:::-;:39;12857:107;;;12919:36;;;;;;;;;;;;;;12857:107;12976:23;12988:2;12992:6;12976:11;:23::i;:::-;12533:471:::0;;:::o;13188:150::-;1094:13:0;:11;:13::i;:::-;6116:11:5;:23;;;;;;13243:60:::1;;13277:19;;-1:-1:-1::0;;;13277:19:5::1;;;;;;;;;;;13243:60;13308:25;13314:10;13326:6;13308:5;:25::i;:::-;13188:150:::0;:::o;2199:214:6:-;2265:7;2284:12;2280:129;;;-1:-1:-1;;;;;2333:16:6;;;;;;:7;:16;;;;;;2313:37;;:19;:37::i;2280:129::-;-1:-1:-1;;;;;3519:18:1;;3493:7;3519:18;;;;;;;;;;;2378:24:6;3419:125:1;2280:129:6;2199:214;;;:::o;13504:91:5:-;1094:13:0;:11;:13::i;:::-;13565:25:5::1;:23;:25::i;:::-;13504:91::o:0;2369:102:1:-;2425:13;2457:7;2450:14;;;;;:::i;6575:427::-;734:10:4;6668:4:1;4102:18;;;:11;:18;;;;;;;;-1:-1:-1;;;;;4102:27:1;;;;;;;;;;6668:4;;734:10:4;6812:15:1;6792:16;:35;;6784:85;;;;-1:-1:-1;;;6784:85:1;;5286:2:8;6784:85:1;;;5268:21:8;5325:2;5305:18;;;5298:30;5364:34;5344:18;;;5337:62;5435:7;5415:18;;;5408:35;5460:19;;6784:85:1;5084:401:8;6784:85:1;6903:60;6912:5;6919:7;6947:15;6928:16;:34;6903:8;:60::i;:::-;-1:-1:-1;6991:4:1;;6575:427;-1:-1:-1;;;;6575:427:1:o;7860:232:5:-;1094:13:0;:11;:13::i;:::-;6832:11:5;:30;;;;;;7939:74:::1;;7983:23;;;;;;;;;;;;;;7939:74;8018:11;:28;8032:14:::0;8018:11;:28:::1;:::i;:::-;;8057:30;8072:14;8057:30;;;;;;:::i;10534:685::-:0;10625:4;10637:17;10657:30;10668:10;10680:6;10657:10;:30::i;:::-;10637:50;;10693:23;10719:24;10736:6;10719:16;:24::i;:::-;10693:50;-1:-1:-1;10749:24:5;10693:50;10776:18;10785:9;10776:6;:18;:::i;:::-;:36;;;;:::i;:::-;6370:11;:35;10749:63;;-1:-1:-1;6370:35:5;;;;;10819:167;;;10896:24;;10877:16;10861:13;10871:2;10861:9;:13::i;:::-;:32;;;;:::i;:::-;:59;10857:123;;;10939:32;;-1:-1:-1;;;10939:32:5;;-1:-1:-1;;;;;2463:55:8;;10939:32:5;;;2445:74:8;2418:18;;10939:32:5;2299:226:8;10857:123:5;10996:14;;10992:94;;11057:10;;11020:59;;11045:10;;-1:-1:-1;;;;;11057:10:5;11069:9;11020:24;:59::i;:::-;11095:20;;11091:75;;11125:34;11131:10;11143:15;11125:5;:34::i;:::-;11178:36;11193:2;11197:16;11178:14;:36::i;:::-;11171:43;10534:685;-1:-1:-1;;;;;;10534:685:5:o;636:32::-;;;;;;;:::i;1104:88:6:-;1152:7;1174:13;3342:12:1;;;3255:106;1174:13:6;1167:20;;1104:88;:::o;9859:374:5:-;1094:13:0;:11;:13::i;:::-;7449:11:5;:27;;;;;;9935:69:::1;;9973:24;;;;;;;;;;;;;;9935:69;10009:16;10053:13;10043:7;;10028:12;;:22;;;;:::i;:::-;:38;;;;:::i;:::-;10009:57;;558:5;10076:8;:26;10072:79;;;10119:25;::::0;-1:-1:-1;;;10119:25:5;;::::1;::::0;::::1;1550::8::0;;;1523:18;;10119:25:5::1;1404:177:8::0;10072:79:5::1;10156:12;:28:::0;;;10195:33:::1;::::0;10171:13;;10195:33:::1;::::0;;;::::1;9929:304;9859:374:::0;:::o;9249:443::-;1094:13:0;:11;:13::i;:::-;7235:11:5;:22;;;;;;9346:59:::1;;9379:19;;;;;;;;;;;;;;9346:59;9411:16;9455:7;9445;;9430:12;;:22;;;;:::i;:::-;:32;;;;:::i;:::-;9411:51;;558:5;9472:8;:26;9468:79;;;9515:25;::::0;-1:-1:-1;;;9515:25:5;;::::1;::::0;::::1;1550::8::0;;;1523:18;;9515:25:5::1;1404:177:8::0;9468:79:5::1;9552:38;9578:11;9552:25;:38::i;:::-;9596:10;:24:::0;;-1:-1:-1;;9596:24:5::1;-1:-1:-1::0;;;;;9596:24:5;::::1;::::0;;::::1;::::0;;;9626:6:::1;:16:::0;;;9653:34:::1;::::0;9626:16;;9596:24;9653:34:::1;::::0;-1:-1:-1;;9653:34:5::1;9340:352;9249:443:::0;;:::o;13768:115::-;1094:13:0;:11;:13::i;:::-;13845:33:5::1;13869:8;13845:23;:33::i;8822:218::-:0;1094:13:0;:11;:13::i;:::-;7686:11:5;:25;;;;;;8893:65:::1;;8929:22;;-1:-1:-1::0;;;8929:22:5::1;;;;;;;;;;;8893:65;8963:32;8987:7;8963:23;:32::i;:::-;9007:28;::::0;9027:7;;9007:28:::1;::::0;;;::::1;8822:218:::0;:::o;8520:535:1:-;-1:-1:-1;;;;;8603:21:1;;8595:65;;;;-1:-1:-1;;;8595:65:1;;7896:2:8;8595:65:1;;;7878:21:8;7935:2;7915:18;;;7908:30;7974:33;7954:18;;;7947:61;8025:18;;8595:65:1;7694:355:8;8595:65:1;8747:6;8731:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;8899:18:1;;:9;:18;;;;;;;;;;;:28;;;;;;8952:37;1550:25:8;;;8952:37:1;;1523:18:8;8952:37:1;;;;;;;12533:471:5;;:::o;1674:396:7:-;1820:4;1816:2;1812:13;1802:258;;1975:10;1969:4;1962:24;2047:4;2041;2034:18;2074:198:0;1094:13;:11;:13::i;:::-;-1:-1:-1;;;;;2162:22:0;::::1;2154:73;;;::::0;-1:-1:-1;;;2154:73:0;;8256:2:8;2154:73:0::1;::::0;::::1;8238:21:8::0;8295:2;8275:18;;;8268:30;8334:34;8314:18;;;8307:62;8405:8;8385:18;;;8378:36;8431:19;;2154:73:0::1;8054:402:8::0;2154:73:0::1;2237:28;2256:8;2237:18;:28::i;1359:130::-:0;1273:6;;-1:-1:-1;;;;;1273:6:0;734:10:4;1422:23:0;1414:68;;;;-1:-1:-1;;;1414:68:0;;8663:2:8;1414:68:0;;;8645:21:8;;;8682:18;;;8675:30;8741:34;8721:18;;;8714:62;8793:18;;1414:68:0;8461:356:8;10457:340:1;-1:-1:-1;;;;;10558:19:1;;10550:68;;;;-1:-1:-1;;;10550:68:1;;9024:2:8;10550:68:1;;;9006:21:8;9063:2;9043:18;;;9036:30;9102:34;9082:18;;;9075:62;9173:6;9153:18;;;9146:34;9197:19;;10550:68:1;8822:400:8;10550:68:1;-1:-1:-1;;;;;10636:21:1;;10628:68;;;;-1:-1:-1;;;10628:68:1;;9429:2:8;10628:68:1;;;9411:21:8;9468:2;9448:18;;;9441:30;9507:34;9487:18;;;9480:62;9578:4;9558:18;;;9551:32;9600:19;;10628:68:1;9227:398:8;10628:68:1;-1:-1:-1;;;;;10707:18:1;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;10758:32;;1550:25:8;;;10758:32:1;;1523:18:8;10758:32:1;;;;;;;10457:340;;;:::o;14132:237:5:-;14219:17;14267:6;;14277:1;14267:11;;:35;;;;-1:-1:-1;14292:10:5;;-1:-1:-1;;;;;14282:20:5;;;14292:10;;14282:20;;14267:35;14263:102;;;505:6;14334;;14325;:15;;;;:::i;:::-;14324:34;;;;:::i;14555:229::-;14628:23;14688:12;;14704:1;14688:17;14684:96;;505:6;14743:12;;14734:6;:21;;;;:::i;:::-;14733:40;;;;:::i;6980:406:6:-;7092:12;7088:294;;;7118:12;;7114:207;;7142:19;7164:10;:8;:10::i;:::-;7142:32;-1:-1:-1;7184:15:6;7202:21;7142:32;7202:7;:21;:::i;:::-;7184:39;;7234:36;7243:4;7249:2;7253:7;7262;7234:8;:36::i;:::-;7300:2;-1:-1:-1;;;;;7285:27:6;7294:4;-1:-1:-1;;;;;7285:27:6;;7304:7;7285:27;;;;1550:25:8;;1538:2;1523:18;;1404:177;7285:27:6;;;;;;;;7132:189;;7114:207;6980:406;;;:::o;7088:294::-;7341:34;7357:4;7363:2;7367:7;7341:15;:34::i;4609:182::-;4684:12;4680:107;;;4713:19;;-1:-1:-1;;;4713:19:6;;;;;;;;;;;4680:107;4753:27;4765:7;4774:5;4753:11;:27::i;2590:257::-;2702:4;734:10:4;2756:37:6;2772:4;734:10:4;2787:5:6;2756:15;:37::i;:::-;2799:26;2809:4;2815:2;2819:5;2799:9;:26::i;8026:148::-;8068:7;8084:15;8101;8120:19;:17;:19::i;:::-;8083:56;;-1:-1:-1;8083:56:6;-1:-1:-1;8152:17:6;8083:56;;8152:17;:::i;:::-;8145:24;;;;8026:148;:::o;4164:182::-;4239:12;4235:107;;;4268:19;;-1:-1:-1;;;4268:19:6;;;;;;;;;;;4235:107;4308:27;4320:7;4329:5;4308:11;:27::i;1824:101:0:-;1094:13;:11;:13::i;:::-;1888:30:::1;1915:1;1888:18;:30::i;2993:191:6:-:0;3083:4;734:10:4;3135:27:6;734:10:4;3152:2:6;3156:5;3135:9;:27::i;4988:152::-;5053:12;5048:63;;5082:22;;-1:-1:-1;;;5082:22:6;;;;;;;;;;;5048:63;5117:7;:18;4988:152::o;2426:187:0:-;2518:6;;;-1:-1:-1;;;;;2534:17:0;;;-1:-1:-1;;2534:17:0;;;;;;;2566:40;;2518:6;;;2534:17;2518:6;;2566:40;;2499:16;;2566:40;2489:124;2426:187;:::o;8822:406:6:-;-1:-1:-1;;;;;8976:15:6;;8954:19;8976:15;;;:7;:15;;;;;;9001:24;;;8997:112;;;9042:60;;;;;-1:-1:-1;;;;;10023:55:8;;9042:60:6;;;10005:74:8;10095:18;;;10088:34;;;10138:18;;;10131:34;;;9978:18;;9042:60:6;9803:368:8;8997:112:6;-1:-1:-1;;;;;9132:15:6;;;;;;:7;:15;;;;;;:28;;9150:10;;9132:28;:::i;:::-;-1:-1:-1;;;;;9114:15:6;;;;;;;:7;:15;;;;;;:46;;;;9187:18;;;;;;;:36;;9208:15;;9187:36;:::i;:::-;-1:-1:-1;;;;;9166:18:6;;;;;;;:7;:18;;;;;:57;;;;-1:-1:-1;;;;8822:406:6:o;7456:788:1:-;-1:-1:-1;;;;;7552:18:1;;7544:68;;;;-1:-1:-1;;;7544:68:1;;10378:2:8;7544:68:1;;;10360:21:8;10417:2;10397:18;;;10390:30;10456:34;10436:18;;;10429:62;10527:7;10507:18;;;10500:35;10552:19;;7544:68:1;10176:401:8;7544:68:1;-1:-1:-1;;;;;7630:16:1;;7622:64;;;;-1:-1:-1;;;7622:64:1;;10784:2:8;7622:64:1;;;10766:21:8;10823:2;10803:18;;;10796:30;10862:34;10842:18;;;10835:62;10933:5;10913:18;;;10906:33;10956:19;;7622:64:1;10582:399:8;7622:64:1;-1:-1:-1;;;;;7768:15:1;;7746:19;7768:15;;;;;;;;;;;7801:21;;;;7793:72;;;;-1:-1:-1;;;7793:72:1;;11188:2:8;7793:72:1;;;11170:21:8;11227:2;11207:18;;;11200:30;11266:34;11246:18;;;11239:62;11337:8;11317:18;;;11310:36;11363:19;;7793:72:1;10986:402:8;7793:72:1;-1:-1:-1;;;;;7899:15:1;;;:9;:15;;;;;;;;;;;7917:20;;;7899:38;;8114:13;;;;;;;;;;:23;;;;;;8163:26;;1550:25:8;;;8114:13:1;;8163:26;;1523:18:8;8163:26:1;;;;;;;8200:37;7534:710;7456:788;;;:::o;9375:659::-;-1:-1:-1;;;;;9458:21:1;;9450:67;;;;-1:-1:-1;;;9450:67:1;;11595:2:8;9450:67:1;;;11577:21:8;11634:2;11614:18;;;11607:30;11673:34;11653:18;;;11646:62;11744:3;11724:18;;;11717:31;11765:19;;9450:67:1;11393:397:8;9450:67:1;-1:-1:-1;;;;;9613:18:1;;9588:22;9613:18;;;;;;;;;;;9649:24;;;;9641:71;;;;-1:-1:-1;;;9641:71:1;;11997:2:8;9641:71:1;;;11979:21:8;12036:2;12016:18;;;12009:30;12075:34;12055:18;;;12048:62;12146:4;12126:18;;;12119:32;12168:19;;9641:71:1;11795:398:8;9641:71:1;-1:-1:-1;;;;;9746:18:1;;:9;:18;;;;;;;;;;;9767:23;;;9746:44;;9883:12;:22;;;;;;;9931:37;1550:25:8;;;9746:9:1;;:18;9931:37;;1523:18:8;9931:37:1;;;;;;;6980:406:6;;;:::o;11078:411:1:-;-1:-1:-1;;;;;4102:18:1;;;11178:24;4102:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;-1:-1:-1;;11244:37:1;;11240:243;;11325:6;11305:16;:26;;11297:68;;;;-1:-1:-1;;;11297:68:1;;12400:2:8;11297:68:1;;;12382:21:8;12439:2;12419:18;;;12412:30;12478:31;12458:18;;;12451:59;12527:18;;11297:68:1;12198:353:8;11297:68:1;11407:51;11416:5;11423:7;11451:6;11432:16;:25;11407:8;:51::i;3382:374:6:-;3487:12;3483:269;;;3509:31;3535:4;3509:25;:31::i;:::-;3548:29;3574:2;3548:25;:29::i;:::-;3589:6;3599:1;3589:11;3585:62;;3619:19;;;;;;;;;;;;;;3585:62;3655:36;3674:4;3680:2;3684:6;3655:18;:36::i;8270:107::-;8321:7;8330;8353;;8362:9;:7;:9::i;:::-;8345:27;;;;8270:107;;:::o;5725:502::-;5835:12;5850:21;5863:7;5850:12;:21::i;:::-;5835:36;-1:-1:-1;5877:23:6;5903:14;5835:36;5903:7;:14;:::i;:::-;5877:40;;5924:15;5941:12;5955:23;5982:67;6001:7;6016:4;6028:15;5982:11;:67::i;:::-;5923:126;;;;;;6060:7;6071:1;6060:12;6056:167;;6082:53;6091:6;6099:9;6110:7;6119:15;6082:8;:53::i;:::-;6144:23;6156:4;6162;6144:11;:23::i;:::-;6197:9;-1:-1:-1;;;;;6180:36:6;6189:6;-1:-1:-1;;;;;6180:36:6;;6208:7;6180:36;;;;1550:25:8;;1538:2;1523:18;;1404:177;6180:36:6;;;;;;;;6056:167;5829:398;;;;;5725:502;;;:::o;6643:121::-;6704:7;448:6;6737:7;;6727;:17;;;;:::i;7551:376::-;7666:7;7675;7684;7699:19;7721:10;:8;:10::i;:::-;7699:32;-1:-1:-1;7737:15:6;7755:21;7699:32;7755:7;:21;:::i;:::-;7737:39;-1:-1:-1;7782:12:6;7797:18;7804:11;7797:4;:18;:::i;:::-;7782:33;-1:-1:-1;7821:23:6;7847:29;7865:11;7847:15;:29;:::i;:::-;7891:7;;7900:4;;-1:-1:-1;7891:7:6;;-1:-1:-1;7551:376:6;-1:-1:-1;;;;;;7551:376:6:o;6389:128::-;6472:4;6462:7;;:14;;;;:::i;:::-;6452:7;:24;6495:10;;:17;;6508:4;;6495:17;:::i;:::-;6482:10;:30;-1:-1:-1;;6389:128:6:o;14:180:8:-;73:6;126:2;114:9;105:7;101:23;97:32;94:52;;;142:1;139;132:12;94:52;-1:-1:-1;165:23:8;;14:180;-1:-1:-1;14:180:8:o;199:548::-;311:4;340:2;369;358:9;351:21;401:6;395:13;444:6;439:2;428:9;424:18;417:34;469:1;479:140;493:6;490:1;487:13;479:140;;;588:14;;;584:23;;578:30;554:17;;;573:2;550:26;543:66;508:10;;479:140;;;483:3;668:1;663:2;654:6;643:9;639:22;635:31;628:42;738:2;731;727:7;722:2;714:6;710:15;706:29;695:9;691:45;687:54;679:62;;;;199:548;;;;:::o;752:196::-;820:20;;-1:-1:-1;;;;;869:54:8;;859:65;;849:93;;938:1;935;928:12;953:254;1021:6;1029;1082:2;1070:9;1061:7;1057:23;1053:32;1050:52;;;1098:1;1095;1088:12;1050:52;1121:29;1140:9;1121:29;:::i;:::-;1111:39;1197:2;1182:18;;;;1169:32;;-1:-1:-1;;;953:254:8:o;1586:328::-;1663:6;1671;1679;1732:2;1720:9;1711:7;1707:23;1703:32;1700:52;;;1748:1;1745;1738:12;1700:52;1771:29;1790:9;1771:29;:::i;:::-;1761:39;;1819:38;1853:2;1842:9;1838:18;1819:38;:::i;:::-;1809:48;;1904:2;1893:9;1889:18;1876:32;1866:42;;1586:328;;;;;:::o;2108:186::-;2167:6;2220:2;2208:9;2199:7;2195:23;2191:32;2188:52;;;2236:1;2233;2226:12;2188:52;2259:29;2278:9;2259:29;:::i;2530:184::-;-1:-1:-1;;;2579:1:8;2572:88;2679:4;2676:1;2669:15;2703:4;2700:1;2693:15;2719:922;2788:6;2841:2;2829:9;2820:7;2816:23;2812:32;2809:52;;;2857:1;2854;2847:12;2809:52;2897:9;2884:23;2926:18;2967:2;2959:6;2956:14;2953:34;;;2983:1;2980;2973:12;2953:34;3021:6;3010:9;3006:22;2996:32;;3066:7;3059:4;3055:2;3051:13;3047:27;3037:55;;3088:1;3085;3078:12;3037:55;3124:2;3111:16;3146:2;3142;3139:10;3136:36;;;3152:18;;:::i;:::-;3227:2;3221:9;3195:2;3281:13;;-1:-1:-1;;3277:22:8;;;3301:2;3273:31;3269:40;3257:53;;;3325:18;;;3345:22;;;3322:46;3319:72;;;3371:18;;:::i;:::-;3411:10;3407:2;3400:22;3446:2;3438:6;3431:18;3486:7;3481:2;3476;3472;3468:11;3464:20;3461:33;3458:53;;;3507:1;3504;3497:12;3458:53;3563:2;3558;3554;3550:11;3545:2;3537:6;3533:15;3520:46;3608:1;3586:15;;;3603:2;3582:24;3575:35;;;;-1:-1:-1;3590:6:8;2719:922;-1:-1:-1;;;;;2719:922:8:o;3646:260::-;3714:6;3722;3775:2;3763:9;3754:7;3750:23;3746:32;3743:52;;;3791:1;3788;3781:12;3743:52;3814:29;3833:9;3814:29;:::i;:::-;3804:39;;3862:38;3896:2;3885:9;3881:18;3862:38;:::i;:::-;3852:48;;3646:260;;;;;:::o;3911:437::-;3990:1;3986:12;;;;4033;;;4054:61;;4108:4;4100:6;4096:17;4086:27;;4054:61;4161:2;4153:6;4150:14;4130:18;4127:38;4124:218;;-1:-1:-1;;;4195:1:8;4188:88;4299:4;4296:1;4289:15;4327:4;4324:1;4317:15;4124:218;;3911:437;;;:::o;4353:184::-;-1:-1:-1;;;4402:1:8;4395:88;4502:4;4499:1;4492:15;4526:4;4523:1;4516:15;4542:128;4609:9;;;4630:11;;;4627:37;;;4644:18;;:::i;4675:125::-;4740:9;;;4761:10;;;4758:36;;;4774:18;;:::i;4805:274::-;4845:1;4871;4861:189;;-1:-1:-1;;;4903:1:8;4896:88;5007:4;5004:1;4997:15;5035:4;5032:1;5025:15;4861:189;-1:-1:-1;5064:9:8;;4805:274::o;5616:545::-;5718:2;5713:3;5710:11;5707:448;;;5754:1;5779:5;5775:2;5768:17;5824:4;5820:2;5810:19;5894:2;5882:10;5878:19;5875:1;5871:27;5865:4;5861:38;5930:4;5918:10;5915:20;5912:47;;;-1:-1:-1;5953:4:8;5912:47;6008:2;6003:3;5999:12;5996:1;5992:20;5986:4;5982:31;5972:41;;6063:82;6081:2;6074:5;6071:13;6063:82;;;6126:17;;;6107:1;6096:13;6063:82;;;6067:3;;;5616:545;;;:::o;6337:1352::-;6463:3;6457:10;6490:18;6482:6;6479:30;6476:56;;;6512:18;;:::i;:::-;6541:97;6631:6;6591:38;6623:4;6617:11;6591:38;:::i;:::-;6585:4;6541:97;:::i;:::-;6693:4;;6757:2;6746:14;;6774:1;6769:663;;;;7476:1;7493:6;7490:89;;;-1:-1:-1;7545:19:8;;;7539:26;7490:89;-1:-1:-1;;6294:1:8;6290:11;;;6286:24;6282:29;6272:40;6318:1;6314:11;;;6269:57;7592:81;;6739:944;;6769:663;5563:1;5556:14;;;5600:4;5587:18;;-1:-1:-1;;6805:20:8;;;6923:236;6937:7;6934:1;6931:14;6923:236;;;7026:19;;;7020:26;7005:42;;7118:27;;;;7086:1;7074:14;;;;6953:19;;6923:236;;;6927:3;7187:6;7178:7;7175:19;7172:201;;;7248:19;;;7242:26;-1:-1:-1;;7331:1:8;7327:14;;;7343:3;7323:24;7319:37;7315:42;7300:58;7285:74;;7172:201;-1:-1:-1;;;;;7419:1:8;7403:14;;;7399:22;7386:36;;-1:-1:-1;6337:1352:8:o;9630:168::-;9703:9;;;9734;;9751:15;;;9745:22;;9731:37;9721:71;;9772:18;;:::i","linkReferences":{},"immutableReferences":{"860":[{"start":994,"length":32}],"862":[{"start":1305,"length":32}],"888":[{"start":1228,"length":32}],"890":[{"start":947,"length":32}],"1852":[{"start":2844,"length":32},{"start":5002,"length":32},{"start":5180,"length":32},{"start":5313,"length":32},{"start":5418,"length":32},{"start":6803,"length":32}]}}}}}}},"signatures":{"function":[{"signature":"allowance(address,address)","signatureHash4":"0xdd62ed3e","signatureHash32":"0xdd62ed3e90e97b3d417db9c0c7522647811bafca5afc6694f143588d255fdfb4"},{"signature":"approve(address,uint256)","signatureHash4":"0x095ea7b3","signatureHash32":"0x095ea7b334ae44009aa867bfb386f5c3b4b443ac6f0ee573fa91c4608fbadfba"},{"signature":"balanceOf(address)","signatureHash4":"0x70a08231","signatureHash32":"0x70a08231b98ef4ca268c9cc3f6b4590e4bfec28280db06bb5d45e689f2a360be"},{"signature":"burn(uint256)","signatureHash4":"0x42966c68","signatureHash32":"0x42966c689b5afe9b9b3f8a7103b2a19980d59629bfd6a20a60972312ed41d836"},{"signature":"decimals()","signatureHash4":"0x313ce567","signatureHash32":"0x313ce567add4d438edf58b94ff345d7d38c45b17dfc0f947988d7819dca364f9"},{"signature":"decreaseAllowance(address,uint256)","signatureHash4":"0xa457c2d7","signatureHash32":"0xa457c2d77307f80ff2f3ac810ec99eb18ae2cffee13b29c90c9324546e374be5"},{"signature":"deflationBPS()","signatureHash4":"0x542e9667","signatureHash32":"0x542e9667da8ce4d97b201542721513139c03b8e5321c97837a4a44643edccea2"},{"signature":"documentUri()","signatureHash4":"0x044ab74e","signatureHash32":"0x044ab74ea8f46c64990d22291216f5ee37fc3e2a2c4b2604faf9a049ff1d0e60"},{"signature":"increaseAllowance(address,uint256)","signatureHash4":"0x39509351","signatureHash32":"0x39509351d3325647dde3fdd3c8b249adfe89ef4f16d76d83768e6df7a5cd81d6"},{"signature":"initialDocumentUri()","signatureHash4":"0xa9d86685","signatureHash32":"0xa9d86685cdaa51f3e628293f544f18619ca0459635c88a438cb3edb6667f186d"},{"signature":"initialMaxTokenAmountPerAddress()","signatureHash4":"0xa32f6976","signatureHash32":"0xa32f6976f90d8d94aea6ab95ac8b564fe32373b7c0abb850c0cbf86dbedf7a8f"},{"signature":"initialSupply()","signatureHash4":"0x378dc3dc","signatureHash32":"0x378dc3dcf3fdd8ba45cdf9a7c84030cc136be0ba86f37b5aff34e42175e83e69"},{"signature":"initialTokenOwner()","signatureHash4":"0x8dac7191","signatureHash32":"0x8dac71911b771bb1f522891352372f1c6e6c49123404ddb8aeb5dafb0b1abf4c"},{"signature":"isBurnable()","signatureHash4":"0x883356d9","signatureHash32":"0x883356d97ffbbacc6e2855994453f5afe990dc71bf4d3656ce254c8216c873dc"},{"signature":"isDeflationary()","signatureHash4":"0x8e8c10a2","signatureHash32":"0x8e8c10a2e76e7483a190f6375215376868f2e81de84175d756c036c36dfb1013"},{"signature":"isDocumentUriAllowed()","signatureHash4":"0xf820f567","signatureHash32":"0xf820f5679e5db03bd8503999edee404a93cbf15fe5ed0de952dae5d144705e5e"},{"signature":"isMaxAmountOfTokensSet()","signatureHash4":"0x5a3990ce","signatureHash32":"0x5a3990ce810ed6b53f390ff3a673396556b7b098c0e63a2138b4327d789b94f9"},{"signature":"isMaxSupplySet()","signatureHash4":"0xde0060ca","signatureHash32":"0xde0060ca9f12cccaf7e7bac67335840fd24b2726c7ebf692e7da5119ca53e609"},{"signature":"isMintable()","signatureHash4":"0x46b45af7","signatureHash32":"0x46b45af756cd8f481e4998314f926bb2819aa448ce234bd135e9f9d545541896"},{"signature":"isReflective()","signatureHash4":"0x2e0ee48e","signatureHash32":"0x2e0ee48eba32e70dafd1dcfce123db22e33a693c67cd7d6a9b879e0781952a62"},{"signature":"isTaxable()","signatureHash4":"0x4ac0bc32","signatureHash32":"0x4ac0bc3225172118e648b24fc8ff9ed9d822c47a0e3cee362d8d97695cd49dc5"},{"signature":"maxTokenAmountPerAddress()","signatureHash4":"0xd48e4127","signatureHash32":"0xd48e41272d79b787c6c4cc4e4699d6e38bc8e4d2dd8e488e563f2d47bd6de00b"},{"signature":"maxTotalSupply()","signatureHash4":"0x2ab4d052","signatureHash32":"0x2ab4d052737b45e19a6a2bf1c28dc0e70c82bf75dbd0c7b8ae2d18d0479b7b37"},{"signature":"mint(address,uint256)","signatureHash4":"0x40c10f19","signatureHash32":"0x40c10f19c047ae7dfa66d6312b683d2ea3dfbcb4159e96b967c5f4b0a86f2842"},{"signature":"name()","signatureHash4":"0x06fdde03","signatureHash32":"0x06fdde0383f15d582d1a74511486c9ddf862a882fb7904b3d9fe9b8b8e58a796"},{"signature":"owner()","signatureHash4":"0x8da5cb5b","signatureHash32":"0x8da5cb5b36e7f68c1d2e56001220cdbdd3ba2616072f718acfda4a06441a807d"},{"signature":"renounceOwnership()","signatureHash4":"0x715018a6","signatureHash32":"0x715018a616b5f2044428f6fadb7deef4ce9ca76ef60ea57978964ad137bbe7ae"},{"signature":"setDeflationConfig(uint256)","signatureHash4":"0xd8f67851","signatureHash32":"0xd8f67851c8bff939d9ecdaae744ef755cb46c17ead23802971c1db131fedfb09"},{"signature":"setDocumentUri(string)","signatureHash4":"0xa476df61","signatureHash32":"0xa476df6148647249ffd081f3bd964be9b12c4ab6c1f74403a589ea8e9ca6f0f6"},{"signature":"setMaxTokenAmountPerAddress(uint256)","signatureHash4":"0x02252c4d","signatureHash32":"0x02252c4d6baf076f11a693b0d749295221dac1b60ee640e914ffb53483e30ca2"},{"signature":"setReflectionConfig(uint256)","signatureHash4":"0xf91f825d","signatureHash32":"0xf91f825d4612cc1f03a786d5b94d5cdca622988d7487a797e858580a0718353a"},{"signature":"setTaxConfig(address,uint256)","signatureHash4":"0xf19c4e3b","signatureHash32":"0xf19c4e3bdaa03c69ccb901a7be4893046c9896f02e1c91000ce702ccd352964f"},{"signature":"symbol()","signatureHash4":"0x95d89b41","signatureHash32":"0x95d89b41e2f5f391a79ec54e9d87c79d6e777c63e32c28da95b4e9e4a79250ec"},{"signature":"taxAddress()","signatureHash4":"0xb7bda68f","signatureHash32":"0xb7bda68fb87b800303174c0e23a2c801a2bae5ff233c88367cbf02909a2ce5af"},{"signature":"taxBPS()","signatureHash4":"0x2fa782eb","signatureHash32":"0x2fa782eb323399de8c3f5dbcf79da566d4b3051b592f46ae6b43bb9d2686d8b9"},{"signature":"tFeeBPS()","signatureHash4":"0x9703a19d","signatureHash32":"0x9703a19d46992947e2996a9b130ed3c0dbf714c71e2366ce87b69e3e095e6524"},{"signature":"tokenFromReflection(uint256)","signatureHash4":"0x2d838119","signatureHash32":"0x2d8381191e334c5c786aeda7a1cf0d1fcab48156571efdf460679491abd925e0"},{"signature":"totalSupply()","signatureHash4":"0x18160ddd","signatureHash32":"0x18160ddd7f15c72528c2f94fd8dfe3c8d5aa26e2c50c7d81f4bc7bee8d4b7932"},{"signature":"transfer(address,uint256)","signatureHash4":"0xa9059cbb","signatureHash32":"0xa9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b"},{"signature":"transferFrom(address,address,uint256)","signatureHash4":"0x23b872dd","signatureHash32":"0x23b872dd7302113369cda2901243429419bec145408fa8b352b3dd92b66c680b"},{"signature":"transferOwnership(address)","signatureHash4":"0xf2fde38b","signatureHash32":"0xf2fde38b092330466c661fc723d5289b90272a3e580e3187d1d7ef788506c557"},{"signature":"_tTotal()","signatureHash4":"0xaf465a27","signatureHash32":"0xaf465a27c96206dc190e68538beedf06b2ac94e620a547ebe1577b8e1da41de5"},{"signature":"VERSION()","signatureHash4":"0xffa1ad74","signatureHash32":"0xffa1ad74ba96b4c159a84d090433911c3991c54f629eb60d0c84aed3be5f067c"}],"event":[{"signature":"Approval(address,address,uint256)","signatureHash4":"0x8c5be1e5","signatureHash32":"0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"},{"signature":"DeflationConfigSet(uint256)","signatureHash4":"0xc1ff65ee","signatureHash32":"0xc1ff65ee907dc079b64ed9913d53f4bd593bd6ebd9b2a2708db2916d49e17ec3"},{"signature":"DocumentUriSet(string)","signatureHash4":"0x4456a0b5","signatureHash32":"0x4456a0b562609d67398ddb488f136db285cd3c92343e0a7ba684925669237ade"},{"signature":"MaxTokenAmountPerSet(uint256)","signatureHash4":"0x2905481c","signatureHash32":"0x2905481c6fd1a037492016c4760435a52203d82a6f34dc3de40f464c1bf42d59"},{"signature":"OwnershipTransferred(address,address)","signatureHash4":"0x8be0079c","signatureHash32":"0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0"},{"signature":"ReflectionConfigSet(uint256)","signatureHash4":"0x76e12964","signatureHash32":"0x76e1296412dac7b50002658bf9aab02d0cfe366f373222d5c14d0168ee8199e3"},{"signature":"TaxConfigSet(address,uint256)","signatureHash4":"0xacc44e32","signatureHash32":"0xacc44e32fd5ca4240f6dbe6e8cf4eb49349c17c5ce5f80f1919a9c97b50d398a"},{"signature":"Transfer(address,address,uint256)","signatureHash4":"0xddf252ad","signatureHash32":"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"}],"error":[{"signature":"BurningNotEnabled()","signatureHash4":"0x6cb59139","signatureHash32":"0x6cb5913915573bc6785911ad28fe504ce5b7a39a4087b94887653ebe647b6660"},{"signature":"DestBalanceExceedsMaxAllowed(address)","signatureHash4":"0xf6202a8f","signatureHash32":"0xf6202a8f53614fdecd0d645fed6017ed0f955dffff37bd84b08f0aae029379c5"},{"signature":"DocumentUriNotAllowed()","signatureHash4":"0x70a43fce","signatureHash32":"0x70a43fce1f6b5990756687975f9c877e72ebdaeb3cbc6ce1da69f7b59d98ff9a"},{"signature":"ERC20InsufficientBalance(address,uint256,uint256)","signatureHash4":"0xe450d38c","signatureHash32":"0xe450d38cd8d9f7d95077d567d60ed49c7254716e6ad08fc9872816c97e0ffec6"},{"signature":"InvalidDecimals(uint8)","signatureHash4":"0xca950391","signatureHash32":"0xca95039179831387d9f88b29bca783e0c56dadbcb272cbea828e4360d684fbec"},{"signature":"InvalidMaxSupplyConfig()","signatureHash4":"0xb51a8482","signatureHash32":"0xb51a8482dc5164579876835cb508b62484f914fb889f4420653d59d93ba07575"},{"signature":"InvalidMaxTokenAmount(uint256)","signatureHash4":"0x64824b8d","signatureHash32":"0x64824b8de6a372921f4b427c5b0bcb3e1e5cfdd7b795d1ad19b76555a7b6be38"},{"signature":"InvalidReflectiveConfig()","signatureHash4":"0x30a870cc","signatureHash32":"0x30a870cc67506c4c60690285955f7e9082081c9dfc0ff94d59122e0b37bc3e16"},{"signature":"InvalidTotalBPS(uint256)","signatureHash4":"0x3e474e0d","signatureHash32":"0x3e474e0d2d413c20b452e8c4ee8c9c2533a87e94df7ec76a294dd21be53b368b"},{"signature":"MaxTokenAmountNotAllowed()","signatureHash4":"0x6273340f","signatureHash32":"0x6273340fbe787325662d34d9d760371d7cb17a4adae4d3db89fc2447571a41f7"},{"signature":"MaxTokenAmountPerAddrLtPrevious()","signatureHash4":"0xa43d2d76","signatureHash32":"0xa43d2d761dc8ba49de8df1047439fded45ac22ff6351ac608f8a2ca1ac5d9220"},{"signature":"MintingNotEnabled()","signatureHash4":"0x3990ac68","signatureHash32":"0x3990ac687945526229dc2269188c355ae1d88bc53cd885fba615ec32f10d11d4"},{"signature":"TokenIsNotDeflationary()","signatureHash4":"0xcd9e5298","signatureHash32":"0xcd9e5298e7461c41fccb957743a26da57281e64e3e9fb6fa09b4d3fc57f44f4c"},{"signature":"TokenIsNotReflective()","signatureHash4":"0x800e34b0","signatureHash32":"0x800e34b016e9656f3af02435de2ba15fdf62c9aa41ebe4b3f168677dedd9ee2d"},{"signature":"TokenIsNotTaxable()","signatureHash4":"0xc8a478a5","signatureHash32":"0xc8a478a5143ffd6e8a38a43ab87f943a4c972b9c5f2a46d1dea4b3ab10f19f09"},{"signature":"TotalReflectionTooSmall()","signatureHash4":"0xc91fa8bc","signatureHash32":"0xc91fa8bc383b9962e0cd6a7a9c2a6742aacfd4c4b4684eec07abd9daf8af6848"},{"signature":"TotalSupplyExceedsMaxAllowedAmount()","signatureHash4":"0x44ea8ea5","signatureHash32":"0x44ea8ea517c23e8d19d7cf7b7c900e31867a014325305626356eb514598b9461"},{"signature":"ZeroTransferError()","signatureHash4":"0x76c4f5b3","signatureHash32":"0x76c4f5b38199cbf36cf3c5a142d48c4402bb53699a247842b969bb197837563a"}]},"proxyResolution":{"isProxy":false,"proxyType":null,"implementations":[]},"match":"exact_match","chainId":"56","address":"0x00f8Da33734FeB9b946fEC2228C25072D2e2E41f"}