false
true
0

Contract Address Details

0xAB94E03153e3526A5Aaf5eFe1c7FE41E2F9761bB

Contract Name
DeployPsmSpell
Creator
0xbcaee0–64cea5 at 0x8e0bf8–4d33bb
Balance
0 PLS ( )
Tokens
Fetching tokens...
Transactions
0 Transactions
Transfers
0 Transfers
Gas Used
Fetching gas used...
Last Balance Update
26334734
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
This contract has been partially verified via Sourcify. View contract in Sourcify repository
Contract name:
DeployPsmSpell




Optimization enabled
true
Compiler version
v0.8.28+commit.7893614a




Optimization runs
200
EVM Version
istanbul




Verified at
2026-04-12T02:35:22.382950Z

Constructor Arguments

60e060405234801561001057600080fd5b50604051610f4c380380610f4c83398101604081905261002f91610281565b6001600160a01b03808316608052811660a08190526040805163313ce56760e01b815290516000929163313ce5679160048083019260209291908290030181865afa158015610082573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100a691906102b4565b905060128160ff16111561010b5760405162461bcd60e51b815260206004820152602260248201527f5069704a6f696e2f756e737570706f727465642d646563696d616c732d67742d604482015261062760f31b606482015260840160405180910390fd5b60ff811660c0526706f05b59d3b200006004556ec097ce7bc90715b34b9f1000000000600555670d2f13f7789f0000600655600280546001600160a01b03191633179055604080518082019091528061016d670de0b6b3a764000060016102de565b8152600060209182018190528251905501516001805460ff19169115159190911781557f282f5690f036ef4ea4bac95238e731bbb4d05f746b72df99dd740cef482259a6906101c590670de0b6b3a7640000906102de565b60408051918252600060208301520160405180910390a17f91a88a19f6ef384ea8f15e06b9139c98fc19dcbd91a4ba2d218ac43cee29522760045460055460405161021a929190918252602082015260400190565b60405180910390a17fa7a696c280d1b8a49f1f616aaed7fc30ca8ffad2b5de0fa2ca17fbdde2ba940c60065460405161025591815260200190565b60405180910390a1505050610309565b80516001600160a01b038116811461027c57600080fd5b919050565b6000806040838503121561029457600080fd5b61029d83610265565b91506102ab60208401610265565b90509250929050565b6000602082840312156102c657600080fd5b815160ff811681146102d757600080fd5b9392505050565b808202811582820484141761030357634e487b7160e01b600052601160045260246000fd5b92915050565b60805160a05160c051610bff61034d6000396000818161027501526107df0152600081816102e6015261081d015260008181610233015261084f0152610bff6000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c80636f265b93116100b8578063b3bcfa821161007c578063b3bcfa8214610270578063b8fea0a1146102a9578063cf3dd5d5146102b2578063d18d7d89146102bb578063f29c29c4146102ce578063fc0c546a146102e157600080fd5b80636f265b93146102155780637c5e2795146102265780637dc0d1d01461022e5780638efbc0d81461025557806398d5fdca1461026857600080fd5b806355d6c710116100ff57806355d6c710146101b257806357de26a4146101dd57806359e02dd7146101e557806365c4ce7a146101f35780636a1460241461020657600080fd5b80630e5a6c701461013c578063181783581461015e57806319b9dfb514610168578063406953631461017b5780634fce7a2a14610192575b600080fd5b610144610308565b604080519283529015156020830152015b60405180910390f35b6101666103f3565b005b6101666101763660046109b9565b6105ab565b61018460065481565b604051908152602001610155565b6101846101a03660046109db565b60036020526000908152604090205481565b6002546101c5906001600160a01b031681565b6040516001600160a01b039091168152602001610155565b610184610669565b60005460015460ff16610144565b6101666102013660046109db565b6106bd565b610184670de0b6b3a764000081565b600054600154610144919060ff1682565b610184610701565b6101c57f000000000000000000000000000000000000000000000000000000000000000081565b610166610263366004610a0b565b610717565b6101446107d4565b6102977f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff9091168152602001610155565b61018460045481565b61018460055481565b6101666102c93660046109db565b610926565b6101666102dc3660046109db565b610972565b6101c57f000000000000000000000000000000000000000000000000000000000000000081565b33600090815260036020526040812054819060011461036e5760405162461bcd60e51b815260206004820152601760248201527f5069704a6f696e2f6e6f742d77686974656c697374656400000000000000000060448201526064015b60405180910390fd5b600080306001600160a01b03166398d5fdca6040518163ffffffff1660e01b81526004016040805180830381865afa1580156103ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d29190610a24565b91509150806103e55760008054906103e9565b8160015b9350935050509091565b306001600160a01b03166398d5fdca6040518163ffffffff1660e01b81526004016040805180830381865afa92505050801561044c575060408051601f3d908101601f1916820190925261044991810190610a24565b60015b6104a0576001805460ff19169055600080546040517f282f5690f036ef4ea4bac95238e731bbb4d05f746b72df99dd740cef482259a6926104969282521515602082015260400190565b60405180910390a1565b801580156104ae5750600082115b156105015760045460055460408051858152600060208201529081019290925260608201527fd19f98d3aaca020119e9fe2da189c760b3488c9f588e2435e7bda3d8d96fa3689060800160405180910390a15b801561056557604080518082018252838152600160209182018190526000859055805460ff1916811781558251858152918201527f282f5690f036ef4ea4bac95238e731bbb4d05f746b72df99dd740cef482259a691015b60405180910390a15050565b6001805460ff19169055600080546040517f282f5690f036ef4ea4bac95238e731bbb4d05f746b72df99dd740cef482259a6926105599282521515602082015260400190565b6002546001600160a01b031633146105d55760405162461bcd60e51b815260040161036590610a5a565b6000821180156105e457508181115b6106295760405162461bcd60e51b81526020600482015260166024820152755069704a6f696e2f696e76616c69642d626f756e647360501b6044820152606401610365565b6004829055600581905560408051838152602081018390527f91a88a19f6ef384ea8f15e06b9139c98fc19dcbd91a4ba2d218ac43cee2952279101610559565b60015460009060ff166106b65760405162461bcd60e51b81526020600482015260156024820152745069704a6f696e2f696e76616c69642d707269636560581b6044820152606401610365565b5060005490565b6002546001600160a01b031633146106e75760405162461bcd60e51b815260040161036590610a5a565b6001600160a01b0316600090815260036020526040812055565b610714670de0b6b3a76400006001610aa0565b81565b6002546001600160a01b031633146107415760405162461bcd60e51b815260040161036590610a5a565b670de0b6b3a76400008111156107995760405162461bcd60e51b815260206004820152601d60248201527f5069704a6f696e2f666c6f6f722d63616e6e6f742d6578636565642d310000006044820152606401610365565b60068190556040518181527fa7a696c280d1b8a49f1f616aaed7fc30ca8ffad2b5de0fa2ca17fbdde2ba940c9060200160405180910390a150565b6000808061080660ff7f000000000000000000000000000000000000000000000000000000000000000016600a610ba4565b60405163d0578a0160e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018390529192507f00000000000000000000000000000000000000000000000000000000000000009091169063d0578a0190604401602060405180830381865afa9250505080156108b4575060408051601f3d908101601f191682019092526108b191810190610bb0565b60015b6108c357506000928392509050565b806000036108d75750600093849350915050565b60065481908110156108ea5750806108f5565b50670de0b6b3a76400005b6000600454821015801561090b57506005548211155b90508061091957600061091b565b815b969095509350505050565b6002546001600160a01b031633146109505760405162461bcd60e51b815260040161036590610a5a565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b0316331461099c5760405162461bcd60e51b815260040161036590610a5a565b6001600160a01b0316600090815260036020526040902060019055565b600080604083850312156109cc57600080fd5b50508035926020909101359150565b6000602082840312156109ed57600080fd5b81356001600160a01b0381168114610a0457600080fd5b9392505050565b600060208284031215610a1d57600080fd5b5035919050565b60008060408385031215610a3757600080fd5b825160208401519092508015158114610a4f57600080fd5b809150509250929050565b602080825260169082015275141a5c129bda5b8bdb9bdd0b585d5d1a1bdc9a5e995960521b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610ab757610ab7610a8a565b92915050565b6001815b6001841115610af857808504811115610adc57610adc610a8a565b6001841615610aea57908102905b60019390931c928002610ac1565b935093915050565b600082610b0f57506001610ab7565b81610b1c57506000610ab7565b8160018114610b325760028114610b3c57610b58565b6001915050610ab7565b60ff841115610b4d57610b4d610a8a565b50506001821b610ab7565b5060208310610133831016604e8410600b8410161715610b7b575081810a610ab7565b610b886000198484610abd565b8060001904821115610b9c57610b9c610a8a565b029392505050565b6000610a048383610b00565b600060208284031215610bc257600080fd5b505191905056fea26469706673582212203d49134546954b6a36d2355e74e77f2ee69cb8f428f0f228486a17276f45ac0864736f6c634300081c0033608060405234801561001057600080fd5b50604051610c54380380610c5483398101604081905261002f916101a9565b3360009081526020818152604091829020600190819055600481815581546001600160a01b038881166001600160a01b0319928316179093556002879055600380549387169390911683179055835163313ce56760e01b81529351919363313ce5679381830193909290918290030181865afa1580156100b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100d791906101e5565b6003805460ff60a01b1916600160a01b60ff9384168102919091179182905560129104909116111561015a5760405162461bcd60e51b815260206004820152602260248201527f47656d4a6f696e2f756e737570706f727465642d646563696d616c732d67742d604482015261062760f31b606482015260840160405180910390fd5b60405133907fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a6090600090a250505061020f565b80516001600160a01b03811681146101a457600080fd5b919050565b6000806000606084860312156101be57600080fd5b6101c78461018d565b9250602084015191506101dc6040850161018d565b90509250925092565b6000602082840312156101f757600080fd5b815160ff8116811461020857600080fd5b9392505050565b610a368061021e6000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c8063957aa58c11610071578063957aa58c146101215780639c52a7f114610138578063b3bcfa821461014b578063bf353dbb14610171578063c5ce281e14610191578063ef693bed1461019a57600080fd5b806336569e77146100ae5780633b4da69f146100de57806365fae35e146100f357806369245009146101065780637bd2bea71461010e575b600080fd5b6001546100c1906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100f16100ec3660046107e2565b6101ad565b005b6100f161010136600461080c565b61041c565b6100f1610490565b6003546100c1906001600160a01b031681565b61012a60045481565b6040519081526020016100d5565b6100f161014636600461080c565b6104ef565b60035461015f90600160a01b900460ff1681565b60405160ff90911681526020016100d5565b61012a61017f36600461080c565b60006020819052908152604090205481565b61012a60025481565b6100f16101a83660046107e2565b610562565b6004546001146101f75760405162461bcd60e51b815260206004820152601060248201526f47656d4a6f696e2f6e6f742d6c69766560801b60448201526064015b60405180910390fd5b60035460009061021290600160a01b900460ff166012610844565b61021d90600a61094a565b6102279083610959565b600354909150829061024490600160a01b900460ff166012610844565b61024f90600a61094a565b6102599083610970565b146102a25760405162461bcd60e51b815260206004820152601960248201527847656d4a6f696e2f6f766572666c6f772d6f6e2d7363616c6560381b60448201526064016101ee565b600154600254604051633e6e9fef60e11b815260048101919091526001600160a01b0385811660248301526044820184905290911690637cdd3fde90606401600060405180830381600087803b1580156102fb57600080fd5b505af115801561030f573d6000803e3d6000fd5b50506003546040516323b872dd60e01b8152336004820152306024820152604481018690526001600160a01b0390911692506323b872dd91506064016020604051808303816000875af115801561036a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038e9190610992565b6103d45760405162461bcd60e51b815260206004820152601760248201527623b2b6a537b4b717b330b4b632b216ba3930b739b332b960491b60448201526064016101ee565b826001600160a01b03167fb4e09949657f21548b58afe74e7b86cd2295da5ff1598ae1e5faecb1cf19ca958360405161040f91815260200190565b60405180910390a2505050565b3360009081526020819052604090205460011461044b5760405162461bcd60e51b81526004016101ee906109b4565b6001600160a01b03811660008181526020819052604080822060019055517fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a609190a250565b336000908152602081905260409020546001146104bf5760405162461bcd60e51b81526004016101ee906109b4565b600060048190556040517f2308ed18a14e800c39b86eb6ea43270105955ca385b603b64eca89f98ae8fbda9190a1565b3360009081526020819052604090205460011461051e5760405162461bcd60e51b81526004016101ee906109b4565b6001600160a01b038116600081815260208190526040808220829055517f184450df2e323acec0ed3b5c7531b81f9b4cdef7914dfd4c0a4317416bb5251b9190a250565b6004546001146105a75760405162461bcd60e51b815260206004820152601060248201526f47656d4a6f696e2f6e6f742d6c69766560801b60448201526064016101ee565b6003546000906105c290600160a01b900460ff166012610844565b6105cd90600a61094a565b90506105e0816001600160ff1b03610970565b82111561062b5760405162461bcd60e51b815260206004820152601960248201527847656d4a6f696e2f6f766572666c6f772d6f6e2d7363616c6560381b60448201526064016101ee565b60006106378284610959565b6001546002549192506001600160a01b031690637cdd3fde903361065a856109e4565b6040516001600160e01b031960e086901b16815260048101939093526001600160a01b0390911660248301526044820152606401600060405180830381600087803b1580156106a857600080fd5b505af11580156106bc573d6000803e3d6000fd5b505060035460405163a9059cbb60e01b81526001600160a01b03888116600483015260248201889052909116925063a9059cbb91506044016020604051808303816000875af1158015610713573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107379190610992565b61077d5760405162461bcd60e51b815260206004820152601760248201527623b2b6a537b4b717b330b4b632b216ba3930b739b332b960491b60448201526064016101ee565b836001600160a01b03167f22d324652c93739755cf4581508b60875ebdd78c20c0cff5cf8e23452b299631846040516107b891815260200190565b60405180910390a250505050565b80356001600160a01b03811681146107dd57600080fd5b919050565b600080604083850312156107f557600080fd5b6107fe836107c6565b946020939093013593505050565b60006020828403121561081e57600080fd5b610827826107c6565b9392505050565b634e487b7160e01b600052601160045260246000fd5b60ff828116828216039081111561085d5761085d61082e565b92915050565b6001815b600184111561089e578085048111156108825761088261082e565b600184161561089057908102905b60019390931c928002610867565b935093915050565b6000826108b55750600161085d565b816108c25750600061085d565b81600181146108d857600281146108e2576108fe565b600191505061085d565b60ff8411156108f3576108f361082e565b50506001821b61085d565b5060208310610133831016604e8410600b8410161715610921575081810a61085d565b61092e6000198484610863565b80600019048211156109425761094261082e565b029392505050565b600061082760ff8416836108a6565b808202811582820484141761085d5761085d61082e565b60008261098d57634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156109a457600080fd5b8151801515811461082757600080fd5b60208082526016908201527511d95b529bda5b8bdb9bdd0b585d5d1a1bdc9a5e995960521b604082015260600190565b6000600160ff1b82016109f9576109f961082e565b506000039056fea264697066735822122057880ce88c4c9b49af9b018b5491112feb7f9be0e4a10eb7c8384f2e7a7dcbcc64736f6c634300081c0033610180604052600160035534801561001657600080fd5b506040516118e33803806118e383398101604081905261003591610606565b3360008181526020819052604080822060019055517fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a609190a26001600160a01b0380841660c08190528382166101205290821661014052604080516336569e7760e01b815290516336569e77916004808201926020929091908290030181865afa1580156100c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100eb9190610649565b6001600160a01b031660a0816001600160a01b031681525050826001600160a01b0316637bd2bea76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610142573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101669190610649565b6001600160a01b031660e0816001600160a01b031681525050816001600160a01b031663f4b9fa756040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e19190610649565b6001600160a01b0316610100816001600160a01b031681525050826001600160a01b031663c5ce281e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610239573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025d919061066b565b608081815250506000836001600160a01b031663b3bcfa826040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c89190610684565b905060128160ff1611156103235760405162461bcd60e51b815260206004820152601960248201527f50534d2f67656d2d646563696d616c732d746f6f2d686967680000000000000060448201526064015b60405180910390fd5b61032e8160126106bd565b61033990600a6107c3565b610160526101005160405163095ea7b360e01b81526001600160a01b03858116600483015260001960248301529091169063095ea7b3906044016020604051808303816000875af1158015610392573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103b691906107d2565b6104025760405162461bcd60e51b815260206004820152601660248201527f50534d2f6461692d617070726f76652d6661696c656400000000000000000000604482015260640161031a565b60e05160405163095ea7b360e01b81526001600160a01b03868116600483015260001960248301529091169063095ea7b3906044016020604051808303816000875af1158015610456573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061047a91906107d2565b6104c65760405162461bcd60e51b815260206004820152601660248201527f50534d2f67656d2d617070726f76652d6661696c656400000000000000000000604482015260640161031a565b60a0516040516328ec8bf160e21b81526001600160a01b0385811660048301529091169063a3b22fc490602401600060405180830381600087803b15801561050d57600080fd5b505af1158015610521573d6000803e3d6000fd5b505060a0516040516328ec8bf160e21b81526001600160a01b038881166004830152909116925063a3b22fc49150602401600060405180830381600087803b15801561056c57600080fd5b505af1158015610580573d6000803e3d6000fd5b505060a0516040516328ec8bf160e21b81523060048201526001600160a01b03909116925063a3b22fc49150602401600060405180830381600087803b1580156105c957600080fd5b505af11580156105dd573d6000803e3d6000fd5b50505050505050506107f4565b80516001600160a01b038116811461060157600080fd5b919050565b60008060006060848603121561061b57600080fd5b610624846105ea565b9250610632602085016105ea565b9150610640604085016105ea565b90509250925092565b60006020828403121561065b57600080fd5b610664826105ea565b9392505050565b60006020828403121561067d57600080fd5b5051919050565b60006020828403121561069657600080fd5b815160ff8116811461066457600080fd5b634e487b7160e01b600052601160045260246000fd5b60ff82811682821603908111156106d6576106d66106a7565b92915050565b6001815b6001841115610717578085048111156106fb576106fb6106a7565b600184161561070957908102905b60019390931c9280026106e0565b935093915050565b60008261072e575060016106d6565b8161073b575060006106d6565b8160018114610751576002811461075b57610777565b60019150506106d6565b60ff84111561076c5761076c6106a7565b50506001821b6106d6565b5060208310610133831016604e8410600b841016171561079a575081810a6106d6565b6107a760001984846106dc565b80600019048211156107bb576107bb6106a7565b029392505050565b600061066460ff84168361071f565b6000602082840312156107e457600080fd5b8151801515811461066457600080fd5b60805160a05160c05160e0516101005161012051610140516101605161100c6108d7600039600081816101b60152818161053101526109030152600081816101f4015281816107ce0152610af60152600081816102d2015281816105d30152610bb8015260008181610333015261059001526000818161023601526109620152600081816101360152818161073e01526109a501526000818161018f015281816106390152818161079e01528181610a5e01528181610ac601528181610d180152610dc60152600081816102f9015281816106680152610a16015261100c6000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c8063957aa58c116100ad578063c11645bc11610071578063c11645bc146102cd578063c5ce281e146102f4578063dc4d20fa1461031b578063f4b9fa751461032e578063fae036d51461035557600080fd5b8063957aa58c1461026b57806395991276146102745780639c52a7f114610287578063a3b22fc41461029a578063bf353dbb146102ad57600080fd5b8063626cb3c5116100f4578063626cb3c5146101ef57806365fae35e1461021657806369245009146102295780637bd2bea7146102315780638d7ef9bb1461025857600080fd5b806301664f661461013157806329ae81141461017557806336569e771461018a5780634010f777146101b1578063568d4b6f146101e6575b600080fd5b6101587f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b610188610183366004610e93565b61035e565b005b6101587f000000000000000000000000000000000000000000000000000000000000000081565b6101d87f000000000000000000000000000000000000000000000000000000000000000081565b60405190815260200161016c565b6101d860015481565b6101587f000000000000000000000000000000000000000000000000000000000000000081565b610188610224366004610ed1565b610413565b610188610487565b6101587f000000000000000000000000000000000000000000000000000000000000000081565b610188610266366004610ef3565b6104e6565b6101d860035481565b610188610282366004610ef3565b6108b8565b610188610295366004610ed1565b610c57565b6101886102a8366004610ed1565b610cca565b6101d86102bb366004610ed1565b60006020819052908152604090205481565b6101587f000000000000000000000000000000000000000000000000000000000000000081565b6101d87f000000000000000000000000000000000000000000000000000000000000000081565b610188610329366004610ed1565b610d78565b6101587f000000000000000000000000000000000000000000000000000000000000000081565b6101d860025481565b33600090815260208190526040812054900361038d5760405163ea8e4eb560e01b815260040160405180910390fd5b81623a34b760e91b036103a45760018190556103d5565b81631d1bdd5d60e21b036103bc5760028190556103d5565b604051633494a40d60e21b815260040160405180910390fd5b817fe986e40cc8c151830d4f61050f4fb2e4add8567caad2d5f5496f9158e91fe4c78260405161040791815260200190565b60405180910390a25050565b3360009081526020819052604081205490036104425760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b03811660008181526020819052604080822060019055517fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a609190a250565b3360009081526020819052604081205490036104b65760405163ea8e4eb560e01b815260040160405180910390fd5b600060038190556040517f2308ed18a14e800c39b86eb6ea43270105955ca385b603b64eca89f98ae8fbda9190a1565b60035460000361050957604051634174f77b60e01b815260040160405180910390fd5b8060000361052a57604051631f2a200560e01b815260040160405180910390fd5b60006105567f000000000000000000000000000000000000000000000000000000000000000083610f33565b90506000670de0b6b3a7640000600254836105719190610f33565b61057b9190610f50565b905060006105898284610f72565b90506105b77f0000000000000000000000000000000000000000000000000000000000000000333084610df5565b604051633b4da69f60e01b8152306004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690633b4da69f90604401600060405180830381600087803b15801561061f57600080fd5b505af1158015610633573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663760887037f00000000000000000000000000000000000000000000000000000000000000003030308861069490610f85565b61069d8a610f85565b6040516001600160e01b031960e089901b16815260048101969096526001600160a01b039485166024870152928416604486015292166064840152608483019190915260a482015260c401600060405180830381600087803b15801561070257600080fd5b505af1158015610716573d6000803e3d6000fd5b505060405163ef693bed60e01b81526001600160a01b038881166004830152602482018890527f000000000000000000000000000000000000000000000000000000000000000016925063ef693bed9150604401600060405180830381600087803b15801561078457600080fd5b505af1158015610798573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663bb35783b307f0000000000000000000000000000000000000000000000000000000000000000856b033b2e3c9fd0803ce80000006108059190610f33565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b15801561085457600080fd5b505af1158015610868573d6000803e3d6000fd5b505060408051878152602081018690526001600160a01b03891693507f085d06ecf4c34b237767a31c0888e121d89546a77f186f1987c6b8715e1a8caa9250015b60405180910390a25050505050565b6003546000036108db57604051634174f77b60e01b815260040160405180910390fd5b806000036108fc57604051631f2a200560e01b815260040160405180910390fd5b60006109287f000000000000000000000000000000000000000000000000000000000000000083610f33565b90506000670de0b6b3a7640000600154836109439190610f33565b61094d9190610f50565b9050600061095b8284610fa1565b90506109897f0000000000000000000000000000000000000000000000000000000000000000333087610df5565b604051633b4da69f60e01b8152306004820152602481018590527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690633b4da69f90604401600060405180830381600087803b1580156109f157600080fd5b505af1158015610a05573d6000803e3d6000fd5b5050604051637608870360e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015230602482018190526044820181905260648201526084810186905260a481018690527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031692506376088703915060c401600060405180830381600087803b158015610aac57600080fd5b505af1158015610ac0573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663bb35783b307f0000000000000000000000000000000000000000000000000000000000000000856b033b2e3c9fd0803ce8000000610b2d9190610f33565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b158015610b7c57600080fd5b505af1158015610b90573d6000803e3d6000fd5b505060405163ef693bed60e01b81526001600160a01b038881166004830152602482018590527f000000000000000000000000000000000000000000000000000000000000000016925063ef693bed9150604401600060405180830381600087803b158015610bfe57600080fd5b505af1158015610c12573d6000803e3d6000fd5b505060408051878152602081018690526001600160a01b03891693507fef75f5a47cc9a929968796ceb84f19e7541617b4577f2c228ea95200e15720819250016108a9565b336000908152602081905260408120549003610c865760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b038116600081815260208190526040808220829055517f184450df2e323acec0ed3b5c7531b81f9b4cdef7914dfd4c0a4317416bb5251b9190a250565b336000908152602081905260408120549003610cf95760405163ea8e4eb560e01b815260040160405180910390fd5b6040516328ec8bf160e21b81526001600160a01b0382811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063a3b22fc4906024015b600060405180830381600087803b158015610d5d57600080fd5b505af1158015610d71573d6000803e3d6000fd5b5050505050565b336000908152602081905260408120549003610da75760405163ea8e4eb560e01b815260040160405180910390fd5b604051636e26907d60e11b81526001600160a01b0382811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063dc4d20fa90602401610d43565b6040516323b872dd60e01b81526001600160a01b0384811660048301528381166024830152604482018390528516906323b872dd906064016020604051808303816000875af1158015610e4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e709190610fb4565b610e8d576040516312171d8360e31b815260040160405180910390fd5b50505050565b60008060408385031215610ea657600080fd5b50508035926020909101359150565b80356001600160a01b0381168114610ecc57600080fd5b919050565b600060208284031215610ee357600080fd5b610eec82610eb5565b9392505050565b60008060408385031215610f0657600080fd5b610f0f83610eb5565b946020939093013593505050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610f4a57610f4a610f1d565b92915050565b600082610f6d57634e487b7160e01b600052601260045260246000fd5b500490565b80820180821115610f4a57610f4a610f1d565b6000600160ff1b8201610f9a57610f9a610f1d565b5060000390565b81810381811115610f4a57610f4a610f1d565b600060208284031215610fc657600080fd5b81518015158114610eec57600080fdfea26469706673582212205d9ad6714ce9c2b227deb24c4a848355b353f719cadeb885d144d6c2884be63664736f6c634300081c003360c06040526000600e5534801561001557600080fd5b50604051612393380380612393833981016040819052610034916100de565b6001600160a01b0384811660a052600380546001600160a01b0319908116868416179091556001805490911691841691909117815560808290526b033b2e3c9fd0803ce80000006005553360008181526020819052604080822093909355915190917fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a6091a250505050610129565b80516001600160a01b03811681146100d957600080fd5b919050565b600080600080608085870312156100f457600080fd5b6100fd856100c2565b935061010b602086016100c2565b9250610119604086016100c2565b6060959095015193969295505050565b60805160a0516121d56101be600039600081816102a4015281816105210152818161085901528181610db701528181610e2e01528181610f1c0152818161108a015281816113f501526118ee015260008181610498015281816104f8015281816105a60152818161078d0152818161081f01528181610d7101528181610f8b015281816110470152611c3301526121d56000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c806375f12b2111610104578063b61500e4116100a2578063c5ce281e11610071578063c5ce281e14610493578063cfdd3302146104ba578063d4e8be83146104c3578063d843416d146104d657600080fd5b8063b61500e41461042a578063ba2cdc7514610457578063bf353dbb14610460578063c3b3ad7f1461048057600080fd5b8063898eb267116100de578063898eb2671461035957806396f1b6be1461036c5780639c52a7f11461037f578063b5f522f71461039257600080fd5b806375f12b211461032a5780638033d5811461033357806381a794cb1461034657600080fd5b806329ae81141161017157806349ed59311161014b57806349ed5931146102c65780635c622a0e146102cf578063626cb3c51461030457806365fae35e1461031757600080fd5b806329ae8114146102615780632e77468d1461027457806336569e771461029f57600080fd5b806313d8c840116101ad57806313d8c8401461020a578063152325151461021357806326e027f11461021c5780632755cd2d1461022f57600080fd5b806306661abd146101d45780630cbb5862146101eb5780630f560cd7146101f5575b600080fd5b600b545b6040519081526020015b60405180910390f35b6101f36104e9565b005b6101fd61067f565b6040516101e29190611e11565b6101d860065481565b6101d860055481565b6101f361022a366004611e54565b6106d7565b60085461024990600160401b90046001600160c01b031681565b6040516001600160c01b0390911681526020016101e2565b6101f361026f366004611e6d565b6108fa565b600354610287906001600160a01b031681565b6040516001600160a01b0390911681526020016101e2565b6102877f000000000000000000000000000000000000000000000000000000000000000081565b6101d860075481565b6102e26102dd366004611e54565b610a74565b60408051941515855260208501939093529183015260608201526080016101e2565b600254610287906001600160a01b031681565b6101f3610325366004611ea7565b610afd565b6101d8600e5481565b6101d8610341366004611e54565b610b72565b6101f3610354366004611ec4565b610b93565b6101d8610367366004611f68565b61117a565b600454610287906001600160a01b031681565b6101f361038d366004611ea7565b61151d565b6103eb6103a0366004611e54565b600c60205260009081526040902080546001820154600283015460038401546004909401549293919290916001600160a01b03811691600160a01b9091046001600160601b03169086565b604080519687526020870195909552938501929092526001600160a01b031660608401526001600160601b0316608083015260a082015260c0016101e2565b60085461043e9067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016101e2565b6101d860095481565b6101d861046e366004611ea7565b60006020819052908152604090205481565b600154610287906001600160a01b031681565b6101d87f000000000000000000000000000000000000000000000000000000000000000081565b6101d8600a5481565b6101f36104d1366004611fb2565b611591565b6101f36104e4366004611fb2565b6116da565b604051636cb1c69b60e11b81527f000000000000000000000000000000000000000000000000000000000000000060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063d9638d369060240160a060405180830381865afa158015610570573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105949190611fe2565b600154604051631af24ca760e31b81527f00000000000000000000000000000000000000000000000000000000000000006004820152919650670de0b6b3a764000095506001600160a01b0316935063d792653892506024019050602060405180830381865afa15801561060c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106309190612022565b61063a9083612051565b610644919061206e565b60098190556040519081527f55fdb012a699c045403977212c8fc12fd6d1642fa30eac085dc592c29077ce059060200160405180910390a150565b6060600b8054806020026020016040519081016040528092919081815260200182805480156106cd57602002820191906000526020600020905b8154815260200190600101908083116106b9575b5050505050905090565b336000908152602081905260409020546001146107075760405163ea8e4eb560e01b815260040160405180910390fd5b600d5460010361072a576040516305fb981560e51b815260040160405180910390fd5b6001600d556000818152600c60205260409020600301546001600160a01b03166107675760405163cc16557d60e01b815260040160405180910390fd5b600180546000838152600c60205260409081902090920154915163321c64fd60e21b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260248101929092526001600160a01b03169063c87193f490604401600060405180830381600087803b1580156107e657600080fd5b505af11580156107fa573d6000803e3d6000fd5b5050506000828152600c602052604090819020600201549051633088df1760e11b81527f0000000000000000000000000000000000000000000000000000000000000000600482015230602482015233604482015260648101919091527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169150636111be2e90608401600060405180830381600087803b1580156108a657600080fd5b505af11580156108ba573d6000803e3d6000fd5b505050506108c781611a86565b60405181907f2c5d2826eb5903b8fc201cf48094b858f42f61c7eaac9aaf43ebed490138144e90600090a2506000600d55565b3360009081526020819052604090205460011461092a5760405163ea8e4eb560e01b815260040160405180910390fd5b600d5460010361094d576040516305fb981560e51b815260040160405180910390fd5b6001600d5562313ab360e91b82900361096a576005819055610a31565b81631d185a5b60e21b03610982576006819055610a31565b81630637573760e41b0361099a576007819055610a31565b81630636869760e41b036109ca576008805467ffffffffffffffff191667ffffffffffffffff8316179055610a31565b816207469760ec1b036109fd576008805467ffffffffffffffff16600160401b6001600160c01b03841602179055610a31565b81661cdd1bdc1c195960ca1b03610a1857600e819055610a31565b604051633db0d5b960e01b815260040160405180910390fd5b817fe986e40cc8c151830d4f61050f4fb2e4add8567caad2d5f5496f9158e91fe4c782604051610a6391815260200190565b60405180910390a250506000600d55565b6000818152600c6020526040812060038101546004909101548291829182916001600160a01b038116918391610abb91600160a01b9091046001600160601b031690611b5a565b955090506001600160a01b03821615801590610ad45750805b6000978852600c6020526040909720600281015460019091015497989597909650949350505050565b33600090815260208190526040902054600114610b2d5760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b03811660008181526020819052604080822060019055517fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a609190a250565b600b8181548110610b8257600080fd5b600091825260209091200154905081565b600d54600103610bb6576040516305fb981560e51b815260040160405180910390fd5b6001600d55600e546003908111610be057604051636afb25d560e11b815260040160405180910390fd5b6000878152600c60205260409020600301546001600160a01b031680610c195760405163cc16557d60e01b815260040160405180910390fd5b6000888152600c6020526040812060038101546004909101548291610c4f91600160a01b9091046001600160601b031690611b5a565b925090508015610c7257604051631c6ca9e360e01b815260040160405180910390fd5b5080871015610c94576040516327d10c5960e21b815260040160405180910390fd5b6000898152600c6020526040812060028101546001909101549091808b841115610cbe578b610cc0565b835b9050610ccc8582612051565b915082821115610cea57829150610ce3858361206e565b9050610d4c565b8282108015610cf857508381105b15610d4c5760095480610d0b8486612090565b1015610d4a57808411610d315760405163498489e760e01b815260040160405180910390fd5b610d3b8185612090565b9250610d47868461206e565b91505b505b610d568284612090565b9250610d628185612090565b604051633088df1760e11b81527f000000000000000000000000000000000000000000000000000000000000000060048201523060248201526001600160a01b038c81166044830152606482018490529195507f000000000000000000000000000000000000000000000000000000000000000090911690636111be2e90608401600060405180830381600087803b158015610dfd57600080fd5b505af1158015610e11573d6000803e3d6000fd5b50506001546001600160a01b03169150508815801590610e6357507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168b6001600160a01b031614155b8015610e815750806001600160a01b03168b6001600160a01b031614155b15610eed578a6001600160a01b0316638452c10e3385858e8e6040518663ffffffff1660e01b8152600401610eba9594939291906120a3565b600060405180830381600087803b158015610ed457600080fd5b505af1158015610ee8573d6000803e3d6000fd5b505050505b60025460405163bb35783b60e01b81523360048201526001600160a01b039182166024820152604481018590527f00000000000000000000000000000000000000000000000000000000000000009091169063bb35783b90606401600060405180830381600087803b158015610f6257600080fd5b505af1158015610f76573d6000803e3d6000fd5b50505050806001600160a01b031663c87193f47f000000000000000000000000000000000000000000000000000000000000000087600014610fb85785610fc2565b610fc286886120ef565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381600087803b15801561100057600080fd5b505af1158015611014573d6000803e3d6000fd5b505050505050826000036110305761102b8c611a86565b61110b565b816000036110ef57604051633088df1760e11b81527f000000000000000000000000000000000000000000000000000000000000000060048201523060248201526001600160a01b038681166044830152606482018590527f00000000000000000000000000000000000000000000000000000000000000001690636111be2e90608401600060405180830381600087803b1580156110ce57600080fd5b505af11580156110e2573d6000803e3d6000fd5b5050505061102b8c611a86565b60008c8152600c60205260409020600181018390556002018390555b604080518b81526020810186905290810182905260608101839052608081018490526001600160a01b038616908d907f05e309fd6ce72f2ab888a20056bb4210df08daed86f21f95053deb19964d86b19060a00160405180910390a350506000600d5550505050505050505050565b336000908152602081905260408120546001146111aa5760405163ea8e4eb560e01b815260040160405180910390fd5b600d546001036111cd576040516305fb981560e51b815260040160405180910390fd5b6001600d819055600e5481116111f657604051636afb25d560e11b815260040160405180910390fd5b8560000361121757604051633c76376d60e21b815260040160405180910390fd5b8460000361123857604051637632d31d60e11b815260040160405180910390fd5b6001600160a01b03841661125f5760405163617a951960e11b815260040160405180910390fd5b600a6000815461126e90612102565b91905081905591508160000361129757604051631a93c68960e11b815260040160405180910390fd5b600b80546001818101835560008390527f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db990910184905590546112da9190612090565b6000838152600c6020526040812091825560018201889055600282018790556001600160601b034216600160a01b026001600160a01b03871617600390920191909155611330611328611c21565b600554611dce565b905080600003611353576040516375d00c2f60e01b815260040160405180910390fd5b6000838152600c602052604090206004018190556008546001600160c01b03600160401b8204169067ffffffffffffffff16811515806113935750600081115b156114b0576000670de0b6b3a76400006113ad838c612051565b6113b7919061206e565b6113c190846120ef565b60025460405163f24e23eb60e01b81526001600160a01b0391821660048201528982166024820152604481018390529192507f0000000000000000000000000000000000000000000000000000000000000000169063f24e23eb90606401600060405180830381600087803b15801561143957600080fd5b505af115801561144d573d6000803e3d6000fd5b505060408051878152602081018e90529081018c9052606081018490526001600160a01b03808b1693508b16915088907f7c5bfdc0a5e8192f6cd4972f382cec69116862fb62e6abff8003874c58e064b89060800160405180910390a45061150b565b60408051848152602081018b9052908101899052600060608201526001600160a01b03808816919089169087907f7c5bfdc0a5e8192f6cd4972f382cec69116862fb62e6abff8003874c58e064b89060800160405180910390a45b50506000600d55509095945050505050565b3360009081526020819052604090205460011461154d5760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b038116600081815260208190526040808220829055517f184450df2e323acec0ed3b5c7531b81f9b4cdef7914dfd4c0a4317416bb5251b9190a250565b336000908152602081905260409020546001146115c15760405163ea8e4eb560e01b815260040160405180910390fd5b600d546001036115e4576040516305fb981560e51b815260040160405180910390fd5b6001600d556639b837ba3a32b960c91b82900361161b57600380546001600160a01b0319166001600160a01b03831617905561169f565b8162646f6760e81b0361164857600180546001600160a01b0319166001600160a01b03831617905561169f565b8162766f7760e81b0361167557600280546001600160a01b0319166001600160a01b03831617905561169f565b816363616c6360e01b03610a1857600480546001600160a01b0319166001600160a01b0383161790555b6040516001600160a01b038216815282907f41a50316b758972a692a69178de3d99c3138a652f5213364ee8eff829f22048a90602001610a63565b600d546001036116fd576040516305fb981560e51b815260040160405180910390fd5b6001600d55600e54600290811161172757604051636afb25d560e11b815260040160405180910390fd5b6000838152600c60205260409020600301546001600160a01b0316806117605760405163cc16557d60e01b815260040160405180910390fd5b6000848152600c60205260408120600381015460049091015461179391600160a01b90046001600160601b031690611b5a565b509050806117b457604051631e6a072d60e21b815260040160405180910390fd5b6000858152600c6020526040812060018101546002820154600390920180546001600160a01b0316600160a01b426001600160601b031602179055916117f8611c21565b9050600061180882600554611dce565b90508060000361182b576040516375d00c2f60e01b815260040160405180910390fd5b6000898152600c602052604090206004018190556008546001600160c01b03600160401b8204169067ffffffffffffffff168115158061186b5750600081115b15611a195760095480871080159061188c5750806118898688612051565b10155b156119b8576000670de0b6b3a76400006118a6848a612051565b6118b0919061206e565b6118ba90856120ef565b60025460405163f24e23eb60e01b81526001600160a01b0391821660048201528e82166024820152604481018390529192507f0000000000000000000000000000000000000000000000000000000000000000169063f24e23eb90606401600060405180830381600087803b15801561193257600080fd5b505af1158015611946573d6000803e3d6000fd5b505050508b6001600160a01b03168a6001600160a01b03168e7f275de7ecdd375b5e8049319f8b350686131c219dd4dc450a08e9cf83b03c865f888c8c876040516119aa949392919093845260208401929092526040830152606082015260800190565b60405180910390a450611a13565b6040805185815260208101899052908101879052600060608201526001600160a01b03808d1691908b16908e907f275de7ecdd375b5e8049319f8b350686131c219dd4dc450a08e9cf83b03c865f9060800160405180910390a45b50611a74565b6040805184815260208101889052908101869052600060608201526001600160a01b03808c1691908a16908d907f275de7ecdd375b5e8049319f8b350686131c219dd4dc450a08e9cf83b03c865f9060800160405180910390a45b50506000600d55505050505050505050565b600b805460009190611a9a90600190612090565b81548110611aaa57611aaa61211b565b90600052602060002001549050808214611b03576000828152600c6020526040902054600b805483919083908110611ae457611ae461211b565b6000918252602080832090910192909255838152600c90915260409020555b600b805480611b1457611b14612131565b600082815260208082208301600019908101839055909201909255928152600c909252506040812081815560018101829055600281018290556003810182905560040155565b60045460009081906001600160a01b031663487a239584611b846001600160601b03881642612090565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401602060405180830381865afa158015611bc5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611be99190612022565b600654909150611c026001600160601b03861642612090565b1180611c185750600754611c168285611df8565b105b91509250929050565b600354604051636cb1c69b60e11b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260009182916001600160a01b039091169063d9638d36906024016040805180830381865afa158015611c8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb19190612147565b509050600080826001600160a01b03166359e02dd76040518163ffffffff1660e01b81526004016040805180830381865afa158015611cf4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d189190612175565b9150915080611d395760405162bfc92160e01b815260040160405180910390fd5b611dc6611d4a633b9aca0084612051565b600360009054906101000a90046001600160a01b03166001600160a01b031663495d32cb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dc19190612022565b611df8565b935050505090565b60006b033b2e3c9fd0803ce8000000611de78385612051565b611df1919061206e565b9392505050565b600081611de76b033b2e3c9fd0803ce800000085612051565b602080825282518282018190526000918401906040840190835b81811015611e49578351835260209384019390920191600101611e2b565b509095945050505050565b600060208284031215611e6657600080fd5b5035919050565b60008060408385031215611e8057600080fd5b50508035926020909101359150565b6001600160a01b0381168114611ea457600080fd5b50565b600060208284031215611eb957600080fd5b8135611df181611e8f565b60008060008060008060a08789031215611edd57600080fd5b8635955060208701359450604087013593506060870135611efd81611e8f565b9250608087013567ffffffffffffffff811115611f1957600080fd5b8701601f81018913611f2a57600080fd5b803567ffffffffffffffff811115611f4157600080fd5b896020828401011115611f5357600080fd5b60208201935080925050509295509295509295565b60008060008060808587031215611f7e57600080fd5b84359350602085013592506040850135611f9781611e8f565b91506060850135611fa781611e8f565b939692955090935050565b60008060408385031215611fc557600080fd5b823591506020830135611fd781611e8f565b809150509250929050565b600080600080600060a08688031215611ffa57600080fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b60006020828403121561203457600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176120685761206861203b565b92915050565b60008261208b57634e487b7160e01b600052601260045260246000fd5b500490565b818103818111156120685761206861203b565b60018060a01b038616815284602082015283604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b808201808211156120685761206861203b565b6000600182016121145761211461203b565b5060010190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b6000806040838503121561215a57600080fd5b825161216581611e8f565b6020939093015192949293505050565b6000806040838503121561218857600080fd5b8251915060208301518015158114611fd757600080fdfea264697066735822122096d430768b7ebdb5ecabf0a9a9d8b1be76126e3d57b80b0c57810258d5e78a6064736f6c634300081c003300000000000000000000000016ca93f2f65d5495c874109fff38d11d39850b670000000000000000000000005113111a6b9dbeb84707c0d596cca11ae4ee81960000000000000000000000003fa88872368b9bfea50c35b35fff55c425c8ac530000000000000000000000002030803a2eab2a481f4ff358731c416eead94210000000000000000000000000efd766ccb38eaf1dfd701853bfce31359239f305425249444745442d444149000000000000000000000000000000000000000000000000000000000000000000e3d5de07962ca32a7c19385d38014e5bb57dfd870000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000038d7ea4c68000000000000000000000000006d79f82328ea3da61e066ebb2f88a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e8cd8a657b95bca51dd7bc35cd9d5dfbf9c05596000000000000000000000000aa89d1c41c12ebd230226907025472dbd687f1b8000000000000000000000000579d394e98bc8377038669e5a70961a24412a5e60000000000000000000000000000000000000000033b2e3c9fd0803ce80000000000000000000000000000000000000000000000000000000000000000005460000000000000000000000000000000000000000002e87669c308736a04000000000000000000000000000006d79f82328ea3da61e066ebb2f88a0000000000000000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000f59b2a5dcdf3f1e899b81756970508f1e8af2fb8
              

DeployNewPsmSpell.sol

// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.20;

// ──────────────────────────────────────────────
// INTERFACES
// ──────────────────────────────────────────────
interface GemLike {
    function transfer(address dst, uint256 wad) external returns (bool);
    function transferFrom(address src, address dst, uint256 wad) external returns (bool);
    function approve(address usr, uint256 wad) external returns (bool);
    function balanceOf(address usr) external view returns (uint256);
    function allowance(address owner, address spender) external view returns (uint256);
    function decimals() external view returns (uint8);
}

interface DaiLike is GemLike {
    function push(address usr, uint256 wad) external;
    function pull(address usr, uint256 wad) external;
    function move(address src, address dst, uint256 wad) external;
    function mint(address usr, uint256 wad) external;
    function burn(address usr, uint256 wad) external;
    function permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s) external;
}

interface DaiJoinLike {
    function vat() external view returns (address);
    function dai() external view returns (address);
    function join(address usr, uint256 wad) external;
    function exit(address usr, uint256 wad) external;
}

interface VatLike {
    function wards(address) external view returns (uint256);
    function rely(address) external;
    function deny(address) external;
    function can(address, address) external view returns (uint256);
    function hope(address) external;
    function nope(address) external;
    function ilks(bytes32) external view returns (uint256, uint256, uint256, uint256, uint256);
    function urns(bytes32, address) external view returns (uint256, uint256);
    function gem(bytes32, address) external view returns (uint256);
    function dai(address) external view returns (uint256);
    function sin(address) external view returns (uint256);
    function debt() external view returns (uint256);
    function vice() external view returns (uint256);
    function Line() external view returns (uint256);
    function live() external view returns (uint256);
    function init(bytes32) external;
    function file(bytes32, uint256) external;
    function file(bytes32, bytes32, uint256) external;
    function cage() external;
    function slip(bytes32, address, int256) external;
    function flux(bytes32, address, address, uint256) external;
    function move(address, address, uint256) external;
    function frob(bytes32, address, address, address, int256, int256) external;
    function fork(bytes32, address, address, int256, int256) external;
    function grab(bytes32, address, address, address, int256, int256) external;
    function heal(uint256) external;
    function suck(address, address, uint256) external;
    function fold(bytes32, address, int256) external;
}

interface GemJoinLike {
    function vat() external view returns (address);
    function ilk() external view returns (bytes32);
    function gem() external view returns (address);
    function dec() external view returns (uint8);
    function join(address usr, uint256 wad) external;
    function exit(address usr, uint256 wad) external;
}

interface SpotterLike {
    function rely(address usr) external;
    function file(bytes32 ilk, bytes32 what, address pip) external;
    function file(bytes32 ilk, bytes32 what, uint256 data) external;
    function poke(bytes32 ilk) external;
    function par() external view returns (uint256);
    function ilks(bytes32) external view returns (PipLike, uint256);
}

interface DogLike {
    function rely(address usr) external;
    function file(bytes32 ilk, bytes32 what, address clip) external;
    function file(bytes32 ilk, bytes32 what, uint256 data) external;
    function chop(bytes32) external view returns (uint256);
    function digs(bytes32, uint256) external;
}

interface PaiRegistryLike {
    function addIlk(bytes32 ilk, address gem, address join, address pip, address clip, address pair, address psm) external;
}

interface ISimpleTWAPOracle {
    function getPriceInUsd(address token, uint amountIn) external view returns (uint amountOutDai);
}

interface IERC20 {
    function decimals() external view returns (uint8);
}




interface PipLike {
    function peek() external view returns (bytes32, bool);
}



interface ClipperCallee {
    function clipperCall(address, uint256, uint256, bytes calldata) external;
}

interface AbacusLike {
    function price(uint256, uint256) external view returns (uint256);
}

contract Clipper {
    // ─── Errors ───
    error NotAuthorized();
    error SystemLocked();
    error StoppedIncorrect();
    error FileUnrecognizedParam();
    error ZeroTab();
    error ZeroLot();
    error ZeroUsr();
    error Overflow();
    error ZeroTopPrice();
    error NotRunningAuction();
    error CannotReset();
    error NeedsReset();
    error TooExpensive();
    error NoPartialPurchase();
    error InvalidPrice();

    // ─── Auth ───
    mapping(address => uint256) public wards;
    modifier auth {
        if (wards[msg.sender] != 1) revert NotAuthorized();
        _;
    }

    // ─── Data ───
    bytes32 public immutable ilk;
    VatLike public immutable vat;

    DogLike     public dog;
    address     public vow;
    SpotterLike public spotter;
    AbacusLike  public calc;

    uint256 public buf;
    uint256 public tail;
    uint256 public cusp;
    uint64  public chip;
    uint192 public tip;
    uint256 public chost;

    uint256   public kicks;
    uint256[] public active;

    struct Sale {
        uint256 pos;
        uint256 tab;
        uint256 lot;
        address usr;
        uint96  tic;
        uint256 top;
    }
    mapping(uint256 => Sale) public sales;

    uint256 internal locked;
    uint256 public stopped = 0;

    // ─── Events ───
    event Rely(address indexed usr);
    event Deny(address indexed usr);
    event File(bytes32 indexed what, uint256 data);
    event FileAddress(bytes32 indexed what, address data);
    event Kick(uint256 indexed id, uint256 top, uint256 tab, uint256 lot, address indexed usr, address indexed kpr, uint256 coin);
    event Take(uint256 indexed id, uint256 max, uint256 price, uint256 owe, uint256 tab, uint256 lot, address indexed usr);
    event Redo(uint256 indexed id, uint256 top, uint256 tab, uint256 lot, address indexed usr, address indexed kpr, uint256 coin);
    event Yank(uint256 indexed id);
    event Upchost(uint256 chost);

    // ─── Init ───
    constructor(address vat_, address spotter_, address dog_, bytes32 ilk_) {
        vat     = VatLike(vat_);
        spotter = SpotterLike(spotter_);
        dog     = DogLike(dog_);
        ilk     = ilk_;
        buf     = RAY;
        wards[msg.sender] = 1;
        emit Rely(msg.sender);
    }

    // ─── Sync ───
    modifier lock {
        if (locked == 1) revert SystemLocked();
        locked = 1;
        _;
        locked = 0;
    }

    modifier isStopped(uint256 level) {
        if (stopped >= level) revert StoppedIncorrect();
        _;
    }

    // ─── Admin ───
    function rely(address usr) external auth { wards[usr] = 1; emit Rely(usr); }
    function deny(address usr) external auth { wards[usr] = 0; emit Deny(usr); }

    function file(bytes32 what, uint256 data) external auth lock {
        if      (what == "buf")     buf = data;
        else if (what == "tail")    tail = data;
        else if (what == "cusp")    cusp = data;
        else if (what == "chip")    chip = uint64(data);
        else if (what == "tip")     tip = uint192(data);
        else if (what == "stopped") stopped = data;
        else revert FileUnrecognizedParam();
        emit File(what, data);
    }

    function file(bytes32 what, address data) external auth lock {
        if      (what == "spotter") spotter = SpotterLike(data);
        else if (what == "dog")     dog = DogLike(data);
        else if (what == "vow")     vow = data;
        else if (what == "calc")    calc = AbacusLike(data);
        else revert FileUnrecognizedParam();
        emit FileAddress(what, data);
    }

    // ─── Math ───
    uint256 constant BLN = 10 **  9;
    uint256 constant WAD = 10 ** 18;
    uint256 constant RAY = 10 ** 27;

    function rmul(uint256 x, uint256 y) internal pure returns (uint256 z) {
        z = (x * y) / RAY;
    }
    function rdiv(uint256 x, uint256 y) internal pure returns (uint256 z) {
        z = (x * RAY) / y;
    }

    // ─── Auction ───
    function getFeedPrice() internal view returns (uint256 feedPrice) {
        (PipLike pip, ) = spotter.ilks(ilk);
        (bytes32 val, bool has) = pip.peek();
        if (!has) revert InvalidPrice();
        feedPrice = rdiv(uint256(val) * BLN, spotter.par());
    }

    function kick(
        uint256 tab, uint256 lot, address usr, address kpr
    ) external auth lock isStopped(1) returns (uint256 id) {
        if (tab == 0)         revert ZeroTab();
        if (lot == 0)         revert ZeroLot();
        if (usr == address(0)) revert ZeroUsr();
        
        id = ++kicks;
        if (id == 0) revert Overflow();

        active.push(id);
        sales[id].pos = active.length - 1;
        sales[id].tab = tab;
        sales[id].lot = lot;
        sales[id].usr = usr;
        sales[id].tic = uint96(block.timestamp);

        uint256 top = rmul(getFeedPrice(), buf);
        if (top == 0) revert ZeroTopPrice();
        sales[id].top = top;

        uint256 _tip  = tip;
        uint256 _chip = chip;
        if (_tip > 0 || _chip > 0) {
            uint256 coin = _tip + ((tab * _chip) / WAD);
            vat.suck(vow, kpr, coin);
            emit Kick(id, top, tab, lot, usr, kpr, coin);
        } else {
            emit Kick(id, top, tab, lot, usr, kpr, 0);
        }
    }

    function redo(uint256 id, address kpr) external lock isStopped(2) {
        address usr = sales[id].usr;
        if (usr == address(0)) revert NotRunningAuction();

        (bool done,) = status(sales[id].tic, sales[id].top);
        if (!done) revert CannotReset();

        uint256 tab = sales[id].tab;
        uint256 lot = sales[id].lot;
        sales[id].tic = uint96(block.timestamp);

        uint256 feedPrice = getFeedPrice();
        uint256 top = rmul(feedPrice, buf);
        if (top == 0) revert ZeroTopPrice();
        sales[id].top = top;

        uint256 _tip  = tip;
        uint256 _chip = chip;
        if (_tip > 0 || _chip > 0) {
            uint256 _chost = chost;
            if (tab >= _chost && lot * feedPrice >= _chost) {
                uint256 coin = _tip + ((tab * _chip) / WAD);
                vat.suck(vow, kpr, coin);
                emit Redo(id, top, tab, lot, usr, kpr, coin);
            } else {
                emit Redo(id, top, tab, lot, usr, kpr, 0);
            }
        } else {
            emit Redo(id, top, tab, lot, usr, kpr, 0);
        }
    }

    function take(
        uint256 id, uint256 amt, uint256 max, address who, bytes calldata data
    ) external lock isStopped(3) {
        address usr = sales[id].usr;
        if (usr == address(0)) revert NotRunningAuction();

        uint256 price;
        {
            bool done;
            (done, price) = status(sales[id].tic, sales[id].top);
            if (done) revert NeedsReset();
        }

        if (max < price) revert TooExpensive();

        uint256 lot = sales[id].lot;
        uint256 tab = sales[id].tab;
        uint256 owe;

        {
            uint256 slice = lot <= amt ? lot : amt;
            owe = slice * price;

            if (owe > tab) {
                owe = tab;
                slice = owe / price;
            } else if (owe < tab && slice < lot) {
                uint256 _chost = chost;
                if (tab - owe < _chost) {
                    if (tab <= _chost) revert NoPartialPurchase();
                    owe = tab - _chost;
                    slice = owe / price;
                }
            }

            tab = tab - owe;
            lot = lot - slice;

            vat.flux(ilk, address(this), who, slice);

            DogLike dog_ = dog;
            if (data.length > 0 && who != address(vat) && who != address(dog_)) {
                ClipperCallee(who).clipperCall(msg.sender, owe, slice, data);
            }

            vat.move(msg.sender, vow, owe);
            dog_.digs(ilk, lot == 0 ? tab + owe : owe);
        }

        if (lot == 0) {
            _remove(id);
        } else if (tab == 0) {
            vat.flux(ilk, address(this), usr, lot);
            _remove(id);
        } else {
            sales[id].tab = tab;
            sales[id].lot = lot;
        }

        emit Take(id, max, price, owe, tab, lot, usr);
    }

    function _remove(uint256 id) internal {
        uint256 _move = active[active.length - 1];
        if (id != _move) {
            uint256 _index   = sales[id].pos;
            active[_index]   = _move;
            sales[_move].pos = _index;
        }
        active.pop();
        delete sales[id];
    }

    function count() external view returns (uint256) { return active.length; }
    function list() external view returns (uint256[] memory) { return active; }

    function getStatus(uint256 id) external view returns (bool needsRedo, uint256 price, uint256 lot, uint256 tab) {
        address usr = sales[id].usr;
        bool done;
        (done, price) = status(sales[id].tic, sales[id].top);
        needsRedo = usr != address(0) && done;
        lot = sales[id].lot;
        tab = sales[id].tab;
    }

    function status(uint96 tic, uint256 top) internal view returns (bool done, uint256 price) {
        price = calc.price(top, block.timestamp - tic);
        done  = (block.timestamp - tic > tail || rdiv(price, top) < cusp);
    }

    function upchost() external {
        (,,,, uint256 _dust) = vat.ilks(ilk);
        chost = (_dust * dog.chop(ilk)) / WAD;
        emit Upchost(chost);
    }

    function yank(uint256 id) external auth lock {
        if (sales[id].usr == address(0)) revert NotRunningAuction();
        dog.digs(ilk, sales[id].tab);
        vat.flux(ilk, address(this), msg.sender, sales[id].lot);
        _remove(id);
        emit Yank(id);
    }
}

// ──────────────────────────────────────────────
// PipJoin — with configurable floor (default 0.95)
// ──────────────────────────────────────────────
contract PipJoin {
    event PriceUpdated(uint256 price, bool ok);
    event PriceValidation(uint256 attemptedWad, bool accepted, uint256 minBound, uint256 maxBound);
    event PriceBoundsUpdated(uint256 newMin, uint256 newMax);
    event FloorUpdated(uint256 newFloor);

    struct PriceData {
        uint256 val;
        bool ok;
    }

    ISimpleTWAPOracle public immutable oracle;
    address public immutable token;
    uint8 public immutable dec;

    PriceData public spot;

    address public ward;
    mapping(address => uint256) public bud;

    uint256 public constant WAD = 10 ** 18;
    uint256 public constant INITIAL_PRICE = 1 * WAD;

    uint256 public minPriceWad;
    uint256 public maxPriceWad;

    uint256 public floor;

    constructor(address _oracle, address _token) {
        oracle = ISimpleTWAPOracle(_oracle);
        token = _token;

        uint8 _dec = IERC20(_token).decimals();
        require(_dec <= 18, "PipJoin/unsupported-decimals-gt-18");
        dec = _dec;

        // AUDIT FIX: Changed from 1 to 0.5 WAD. If minPriceWad=1, a 0.949 depeg 
        // fails the inRange check and returns (0, false), breaking the liquidation feed.
        minPriceWad = 5 * 10 ** 17; 
        maxPriceWad = 10 ** 36;

        floor = 95 * 10 ** 16;   // 0.95 * WAD

        ward = msg.sender;
        spot = PriceData(INITIAL_PRICE, false);
        emit PriceUpdated(INITIAL_PRICE, false);
        emit PriceBoundsUpdated(minPriceWad, maxPriceWad);
        emit FloorUpdated(floor);
    }

    modifier auth() { require(msg.sender == ward, "PipJoin/not-authorized"); _; }
    modifier kissed() { require(bud[msg.sender] == 1, "PipJoin/not-whitelisted"); _; }

    function setWard(address newWard) external auth { ward = newWard; }
    function kiss(address who) external auth { bud[who] = 1; }
    function diss(address who) external auth { bud[who] = 0; }

    function setPriceBounds(uint256 newMin, uint256 newMax) external auth {
        require(newMin > 0 && newMax > newMin, "PipJoin/invalid-bounds");
        minPriceWad = newMin;
        maxPriceWad = newMax;
        emit PriceBoundsUpdated(newMin, newMax);
    }

    function setFloor(uint256 newFloor) external auth {
        require(newFloor <= WAD, "PipJoin/floor-cannot-exceed-1");
        floor = newFloor;
        emit FloorUpdated(newFloor);
    }

    function poke() external {
        try this.getPrice() returns (uint256 priceWad, bool success) {
            if (!success && priceWad > 0) {
                emit PriceValidation(priceWad, false, minPriceWad, maxPriceWad);
            }
            if (success) {
                spot = PriceData(priceWad, true);
                emit PriceUpdated(priceWad, true);
            } else {
                spot.ok = false;
                emit PriceUpdated(spot.val, false);
            }
        } catch {
            spot.ok = false;
            emit PriceUpdated(spot.val, false);
        }
    }

    function getPrice() external view returns (uint256 val, bool success) {
        uint256 amountIn = 10 ** uint256(dec);

        try oracle.getPriceInUsd(token, amountIn) returns (uint256 priceForOneToken) {
            if (priceForOneToken == 0) return (0, false);

            uint256 wad = priceForOneToken;

            if (wad < floor) {
                wad = priceForOneToken;        // severe depeg -> report real price
            } else {
                wad = WAD;                     // normal range -> always report exactly 1.0
            }

            bool inRange = (wad >= minPriceWad && wad <= maxPriceWad);
            return (inRange ? wad : 0, inRange);
        } catch {
            return (0, false);
        }
    }

    function peek() external view returns (bytes32, bool) {
        return (bytes32(spot.val), spot.ok);
    }

    function peep() external view kissed returns (bytes32, bool) {
        (uint256 priceWad, bool success) = this.getPrice();
        return success ? (bytes32(priceWad), true) : (bytes32(spot.val), false);
    }

    function read() external view returns (uint256) {
        require(spot.ok, "PipJoin/invalid-price");
        return spot.val;
    }
}

// ──────────────────────────────────────────────
// GemJoin (upgraded to 0.8.20)
// ──────────────────────────────────────────────
contract GemJoin {
    mapping(address => uint256) public wards;
    function rely(address usr) external auth { wards[usr] = 1; emit Rely(usr); }
    function deny(address usr) external auth { wards[usr] = 0; emit Deny(usr); }
    modifier auth { require(wards[msg.sender] == 1, "GemJoin/not-authorized"); _; }

    VatLike public vat;
    bytes32 public ilk;
    GemLike public gem;
    uint8   public dec;
    uint256 public live;

    event Rely(address indexed usr);
    event Deny(address indexed usr);
    event Join(address indexed usr, uint256 wad);
    event Exit(address indexed usr, uint256 wad);
    event Cage();

    constructor(address vat_, bytes32 ilk_, address gem_) {
        wards[msg.sender] = 1;
        live = 1;
        vat = VatLike(vat_);
        ilk = ilk_;
        gem = GemLike(gem_);
        dec = gem.decimals();
        require(dec <= 18, "GemJoin/unsupported-decimals-gt-18");
        emit Rely(msg.sender);
    }

    function cage() external auth { live = 0; emit Cage(); }

    function join(address usr, uint256 wad) external {
        require(live == 1, "GemJoin/not-live");
        uint256 scaledWad = wad * (10 ** (18 - dec));
        require(scaledWad / (10 ** (18 - dec)) == wad, "GemJoin/overflow-on-scale");
        vat.slip(ilk, usr, int256(scaledWad));
        require(gem.transferFrom(msg.sender, address(this), wad), "GemJoin/failed-transfer");
        emit Join(usr, wad);
    }

    function exit(address usr, uint256 wad) external {
    require(live == 1, "GemJoin/not-live");
    uint256 factor = 10 ** (18 - dec);
    require(wad <= uint256(type(int256).max) / factor, "GemJoin/overflow-on-scale");
    uint256 scaledWad = wad * factor;
    vat.slip(ilk, msg.sender, -int256(scaledWad));
    require(gem.transfer(usr, wad), "GemJoin/failed-transfer");
    emit Exit(usr, wad);
}
}

// ──────────────────────────────────────────────
// DssPsm
// ──────────────────────────────────────────────
contract DssPsm {
    error NotAuthorized();
    error InvalidParam();
    error TransferFailed();
    error SystemCaged();
    error ZeroAmount();

    bytes32  public immutable ilk;
    address  public immutable vat;
    address  public immutable gemJoin;
    GemLike  public immutable gem;
    DaiLike  public immutable dai;
    address  public immutable daiJoin;
    address  public immutable vow;

    uint256 public immutable to18ConversionFactor;

    mapping(address => uint256) public wards;

    uint256 public tin;
    uint256 public tout;

    uint256 public live = 1;

    event Rely(address indexed usr);
    event Deny(address indexed usr);
    event File(bytes32 indexed what, uint256 data);
    event SellGem(address indexed owner, uint256 gemAmt, uint256 fee);
    event BuyGem(address indexed owner, uint256 gemAmt, uint256 fee);
    event Cage();

    modifier auth() {
        if (wards[msg.sender] == 0) revert NotAuthorized();
        _;
    }

    modifier whenLive() {
        if (live == 0) revert SystemCaged();
        _;
    }

    constructor(address _gemJoin, address _daiJoin, address _vow) {
        wards[msg.sender] = 1;
        emit Rely(msg.sender);

        gemJoin = _gemJoin;
        daiJoin = _daiJoin;
        vow     = _vow;

        vat = GemJoinLike(_gemJoin).vat();
        gem = GemLike(GemJoinLike(_gemJoin).gem());
        dai = DaiLike(DaiJoinLike(_daiJoin).dai());
        ilk = GemJoinLike(_gemJoin).ilk();

        uint8 gemDec = GemJoinLike(_gemJoin).dec();
        require(gemDec <= 18, "PSM/gem-decimals-too-high");
        to18ConversionFactor = 10 ** (18 - gemDec);

        require(dai.approve(_daiJoin, type(uint256).max), "PSM/dai-approve-failed");
        require(gem.approve(_gemJoin, type(uint256).max), "PSM/gem-approve-failed");

        VatLike(vat).hope(_daiJoin);
        VatLike(vat).hope(_gemJoin);
        VatLike(vat).hope(address(this));
    }

    function _safeTransferFrom(GemLike token, address from, address to, uint256 wad) internal {
        if (!token.transferFrom(from, to, wad)) revert TransferFailed();
    }

    function _safeTransfer(GemLike token, address to, uint256 wad) internal {
        if (!token.transfer(to, wad)) revert TransferFailed();
    }

    function rely(address usr) external auth { wards[usr] = 1; emit Rely(usr); }
    function deny(address usr) external auth { wards[usr] = 0; emit Deny(usr); }

    function file(bytes32 what, uint256 data) external auth {
        if      (what == "tin")  tin = data;
        else if (what == "tout") tout = data;
        else revert InvalidParam();
        emit File(what, data);
    }

    function cage() external auth { live = 0; emit Cage(); }

    function hope(address usr) external auth { VatLike(vat).hope(usr); }
    function nope(address usr) external auth { VatLike(vat).nope(usr); }

    function sellGem(address usr, uint256 gemAmt) external whenLive {
        if (gemAmt == 0) revert ZeroAmount();

        uint256 gemAmt18 = gemAmt * to18ConversionFactor;
        uint256 fee      = (gemAmt18 * tin) / 1e18;
        uint256 daiAmt   = gemAmt18 - fee;

        _safeTransferFrom(gem, msg.sender, address(this), gemAmt);
        GemJoinLike(gemJoin).join(address(this), gemAmt);

        VatLike(vat).frob(ilk, address(this), address(this), address(this),
            int256(gemAmt18), int256(gemAmt18));

        VatLike(vat).move(address(this), vow, fee * 1e27);

        DaiJoinLike(daiJoin).exit(usr, daiAmt);

        emit SellGem(usr, gemAmt, fee);
    }

    function buyGem(address usr, uint256 gemAmt) external whenLive {
        if (gemAmt == 0) revert ZeroAmount();

        uint256 gemAmt18 = gemAmt * to18ConversionFactor;
        uint256 fee      = (gemAmt18 * tout) / 1e18;
        uint256 daiAmt   = gemAmt18 + fee;

        _safeTransferFrom(dai, msg.sender, address(this), daiAmt);
        DaiJoinLike(daiJoin).join(address(this), daiAmt);

        VatLike(vat).frob(ilk, address(this), address(this), address(this),
            -int256(gemAmt18), -int256(gemAmt18));

        GemJoinLike(gemJoin).exit(usr, gemAmt);

        VatLike(vat).move(address(this), vow, fee * 1e27);

        emit BuyGem(usr, gemAmt, fee);
    }

    uint256 internal constant WAD = 1e18;
    uint256 internal constant RAY = 1e27;
}

// ──────────────────────────────────────────────
// Deploy PSM Spell (0.8.20) - PRODUCTION OPTIMIZED
// ──────────────────────────────────────────────
contract DeployPsmSpell {

    struct PsmParams {
        address vat;
        address spotter;
        address daiJoin;
        address vow;
        address gem;
        bytes32 ilk;
        address oracle;
        uint256 tin;
        uint256 tout;
        uint256 line;
        address gemJoin;   
        address registry;  
        address dog;        
        address calc;       
        uint256 buf;        
        uint256 tail;       
        uint256 cusp;       
        uint256 hole;       
        uint256 chop;       
        address exec;        // The GovExec contract
    }

    address public immutable vat;
    address public immutable spotter;
    address public immutable daiJoin;
    address public immutable vow;
    bytes32 public immutable ilk;
    address public immutable gem;
    address public immutable oracle;
    uint256 public immutable tin;
    uint256 public immutable tout;
    uint256 public immutable line;
    address public immutable registry;
    address public immutable inputGemJoin;
    
    address public immutable dog;
    address public immutable calc;
    uint256 public immutable buf;
    uint256 public immutable tail;
    uint256 public immutable cusp;
    uint256 public immutable hole;
    uint256 public immutable chop;
    address public immutable exec; 

    address public immutable pip;
    address public immutable psm;
    address public immutable clip;
    address public immutable gemJoin;

    uint256 constant WAD = 10 ** 18;
    uint256 constant RAY = 10 ** 27;

    event SpellExecuted(
        bytes32 indexed ilk, 
        address indexed psm, 
        address indexed clip,
        uint256 line, 
        uint256 tin, 
        uint256 tout
    );

    constructor(PsmParams memory params) {
        require(params.vat != address(0), "DeployPsmSpell/invalid-vat");
        require(params.spotter != address(0), "DeployPsmSpell/invalid-spotter");
        require(params.daiJoin != address(0), "DeployPsmSpell/invalid-daiJoin");
        require(params.vow != address(0), "DeployPsmSpell/invalid-vow");
        require(params.gem != address(0), "DeployPsmSpell/invalid-gem");
        require(params.oracle != address(0), "DeployPsmSpell/invalid-oracle");
        require(params.line > 0, "DeployPsmSpell/invalid-line");
        require(params.dog != address(0), "DeployPsmSpell/invalid-dog");
        require(params.calc != address(0), "DeployPsmSpell/invalid-calc");
        require(params.exec != address(0), "DeployPsmSpell/invalid-exec");

        vat          = params.vat;
        spotter      = params.spotter;
        daiJoin      = params.daiJoin;
        vow          = params.vow;
        ilk          = params.ilk;
        gem          = params.gem;
        oracle       = params.oracle;
        tin          = params.tin;
        tout         = params.tout;
        line         = params.line;
        registry     = params.registry;
        inputGemJoin = params.gemJoin;
        exec         = params.exec; 

        dog  = params.dog;
        calc = params.calc;
        
        buf  = params.buf  == 0 ? 1055 * 10 ** 24 : params.buf; 
        tail = params.tail == 0 ? 6 hours         : params.tail;
        cusp = params.cusp == 0 ? 9 * 10 ** 26    : params.cusp; 
        hole = params.hole; 
        chop = params.chop == 0 ? WAD             : params.chop; 

            // ==========================================
        // PHASE 1: DEPLOY & HANDOFF
        // msg.sender is your wallet. We set GovExec as ward.
        // ==========================================

        // 1. PipJoin
        pip = address(new PipJoin(oracle, gem));
        PipJoin(pip).kiss(spotter);         
        PipJoin(pip).setWard(exec);     // Overwrites single ward variable. Wallet implicitly removed.

        // 2. GemJoin
        if (inputGemJoin == address(0)) {
            gemJoin = address(new GemJoin(vat, ilk, gem));
            GemJoin(gemJoin).rely(exec);     // Add exec to mapping
            GemJoin(gemJoin).deny(msg.sender); // Explicitly remove wallet from mapping
        } else {
            gemJoin = inputGemJoin;
        }

        // 3. PSM
        psm = address(new DssPsm(gemJoin, daiJoin, vow));
        DssPsm(psm).rely(exec);         // Add exec to mapping FIRST
        DssPsm(psm).deny(msg.sender);   // Remove wallet from mapping SECOND

        // 4. Clipper
        clip = address(new Clipper(vat, spotter, dog, ilk));
        Clipper(clip).rely(exec);       // Add exec to mapping FIRST
        Clipper(clip).deny(msg.sender); // Remove wallet from mapping SECOND
    }

    // ==========================================
    // PHASE 2: CONFIGURATION 
    // Runs via GovExec.delegatecall(). 
    // msg.sender seen by Vat/Spotter/Dog is GovExec.
    // ==========================================
    function execute() external {

        // 1. Spotter Config
        SpotterLike(spotter).rely(pip);
        SpotterLike(spotter).file(ilk, "pip", pip);
        SpotterLike(spotter).file(ilk, "mat", RAY);
        PipJoin(pip).poke();
        SpotterLike(spotter).poke(ilk);

        // 2. Vat Config
        if (inputGemJoin == address(0)) {
            VatLike(vat).init(ilk);       // <--- ADD IT HERE
            VatLike(vat).rely(gemJoin); 
        }
        VatLike(vat).file(ilk, "line", line);
        VatLike(vat).file(ilk, "dust", 0);

        // 3. PSM Config
        DssPsm(psm).file("tin", tin);
        DssPsm(psm).file("tout", tout);
        DssPsm(psm).hope(clip); 

        // 4. Clipper & Dog Config
        VatLike(vat).rely(clip);
        DogLike(dog).rely(clip);
        
        Clipper(clip).file("vow", vow);
        Clipper(clip).file("calc", calc);
        Clipper(clip).file("buf", buf);
        Clipper(clip).file("tail", tail);
        Clipper(clip).file("cusp", cusp);
        Clipper(clip).file("tip", 0);
        Clipper(clip).file("chip", 0);
       
        
        DogLike(dog).file(ilk, "clip", clip);
        DogLike(dog).file(ilk, "chop", chop);
        DogLike(dog).file(ilk, "hole", hole);

        Clipper(clip).upchost();

        // 5. Registry
        if (registry != address(0)) {
            PaiRegistryLike(registry).addIlk(ilk, gem, gemJoin, pip, clip, address(0), psm);
        }

        emit SpellExecuted(ilk, psm, clip, line, tin, tout);
    }


    // ──────────────────────────────────────────────
    // Helpers
    // ──────────────────────────────────────────────
    function bytes32ToString(bytes32 _bytes32) internal pure returns (string memory) {
        bytes memory bytesArray = new bytes(32);
        uint256 len = 0;
        for (uint256 i = 0; i < 32; i++) {
            bytes1 b = _bytes32[i];
            if (b == 0x00) break;
            bytesArray[len] = b;
            len++;
        }
        bytes memory trimmed = new bytes(len);
        for (uint256 i = 0; i < len; i++) trimmed[i] = bytesArray[i];
        return string(trimmed);
    }

    function uintToString(uint256 _i) internal pure returns (string memory) {
        if (_i == 0) return "0";
        uint256 j = _i;
        uint256 len;
        while (j != 0) { len++; j /= 10; }
        bytes memory bstr = new bytes(len);
        uint256 k = len - 1;
        while (_i != 0) {
            bstr[k--] = bytes1(uint8(48 + _i % 10));
            _i /= 10;
        }
        return string(bstr);
    }
}
        

Compiler Settings

{"remappings":[],"optimizer":{"runs":200,"enabled":true},"metadata":{"bytecodeHash":"ipfs"},"libraries":{},"evmVersion":"istanbul","compilationTarget":{"DeployNewPsmSpell.sol":"DeployPsmSpell"}}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"tuple","name":"params","internalType":"struct DeployPsmSpell.PsmParams","components":[{"type":"address","name":"vat","internalType":"address"},{"type":"address","name":"spotter","internalType":"address"},{"type":"address","name":"daiJoin","internalType":"address"},{"type":"address","name":"vow","internalType":"address"},{"type":"address","name":"gem","internalType":"address"},{"type":"bytes32","name":"ilk","internalType":"bytes32"},{"type":"address","name":"oracle","internalType":"address"},{"type":"uint256","name":"tin","internalType":"uint256"},{"type":"uint256","name":"tout","internalType":"uint256"},{"type":"uint256","name":"line","internalType":"uint256"},{"type":"address","name":"gemJoin","internalType":"address"},{"type":"address","name":"registry","internalType":"address"},{"type":"address","name":"dog","internalType":"address"},{"type":"address","name":"calc","internalType":"address"},{"type":"uint256","name":"buf","internalType":"uint256"},{"type":"uint256","name":"tail","internalType":"uint256"},{"type":"uint256","name":"cusp","internalType":"uint256"},{"type":"uint256","name":"hole","internalType":"uint256"},{"type":"uint256","name":"chop","internalType":"uint256"},{"type":"address","name":"exec","internalType":"address"}]}]},{"type":"event","name":"SpellExecuted","inputs":[{"type":"bytes32","name":"ilk","internalType":"bytes32","indexed":true},{"type":"address","name":"psm","internalType":"address","indexed":true},{"type":"address","name":"clip","internalType":"address","indexed":true},{"type":"uint256","name":"line","internalType":"uint256","indexed":false},{"type":"uint256","name":"tin","internalType":"uint256","indexed":false},{"type":"uint256","name":"tout","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"buf","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"calc","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"chop","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"clip","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"cusp","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"daiJoin","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"dog","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"exec","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"execute","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"gem","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"gemJoin","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"hole","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"ilk","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"inputGemJoin","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"line","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"oracle","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"pip","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"psm","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"registry","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"spotter","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"tail","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"tin","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"tout","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"vat","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"vow","inputs":[]}]
              

Contract Creation Code

Verify & Publish
0x61038060405234801561001157600080fd5b50604051617ee3380380617ee383398101604081905261003091610a0d565b80516001600160a01b031661008c5760405162461bcd60e51b815260206004820152601a60248201527f4465706c6f7950736d5370656c6c2f696e76616c69642d76617400000000000060448201526064015b60405180910390fd5b60208101516001600160a01b03166100e65760405162461bcd60e51b815260206004820152601e60248201527f4465706c6f7950736d5370656c6c2f696e76616c69642d73706f7474657200006044820152606401610083565b60408101516001600160a01b03166101405760405162461bcd60e51b815260206004820152601e60248201527f4465706c6f7950736d5370656c6c2f696e76616c69642d6461694a6f696e00006044820152606401610083565b60608101516001600160a01b031661019a5760405162461bcd60e51b815260206004820152601a60248201527f4465706c6f7950736d5370656c6c2f696e76616c69642d766f770000000000006044820152606401610083565b60808101516001600160a01b03166101f45760405162461bcd60e51b815260206004820152601a60248201527f4465706c6f7950736d5370656c6c2f696e76616c69642d67656d0000000000006044820152606401610083565b60c08101516001600160a01b031661024e5760405162461bcd60e51b815260206004820152601d60248201527f4465706c6f7950736d5370656c6c2f696e76616c69642d6f7261636c650000006044820152606401610083565b6000816101200151116102a35760405162461bcd60e51b815260206004820152601b60248201527f4465706c6f7950736d5370656c6c2f696e76616c69642d6c696e6500000000006044820152606401610083565b6101808101516001600160a01b03166102fe5760405162461bcd60e51b815260206004820152601a60248201527f4465706c6f7950736d5370656c6c2f696e76616c69642d646f670000000000006044820152606401610083565b6101a08101516001600160a01b03166103595760405162461bcd60e51b815260206004820152601b60248201527f4465706c6f7950736d5370656c6c2f696e76616c69642d63616c6300000000006044820152606401610083565b6102608101516001600160a01b03166103b45760405162461bcd60e51b815260206004820152601b60248201527f4465706c6f7950736d5370656c6c2f696e76616c69642d6578656300000000006044820152606401610083565b80516001600160a01b0390811660809081526020830151821660a09081526040840151831660c09081526060850151841660e0908152918501516101009081529285015184166101209081529085015184166101409081529185015161016090815292850151610180908152908501516101a09081529285015184166101c09081529185015184166101e05261026085015184166102e05284015183166102005290830151909116610220528101511561047357806101c00151610481565b6b0368acf0993e874a7f0000005b610240526101e08101511561049b57806101e0015161049f565b6154605b61026052610200810151156104b9578061020001516104c7565b6b02e87669c308736a040000005b610280526102208101516102a052610240810151156104eb578061024001516104f5565b670de0b6b3a76400005b6102c052610140516101205160405161050d90610986565b6001600160a01b03928316815291166020820152604001604051809103906000f080158015610540573d6000803e3d6000fd5b506001600160a01b0390811661030081905260a051604051633ca70a7160e21b8152921660048301529063f29c29c490602401600060405180830381600087803b15801561058d57600080fd5b505af11580156105a1573d6000803e3d6000fd5b5050610300516102e05160405163d18d7d8960e01b81526001600160a01b0391821660048201529116925063d18d7d899150602401600060405180830381600087803b1580156105f057600080fd5b505af1158015610604573d6000803e3d6000fd5b50506101e0516001600160a01b03169150610737905057608051610100516101205160405161063290610993565b6001600160a01b03938416815260208101929092529091166040820152606001604051809103906000f08015801561066e573d6000803e3d6000fd5b506001600160a01b039081166103608190526102e0516040516332fd71af60e11b815292166004830152906365fae35e90602401600060405180830381600087803b1580156106bc57600080fd5b505af11580156106d0573d6000803e3d6000fd5b505061036051604051639c52a7f160e01b81523360048201526001600160a01b039091169250639c52a7f19150602401600060405180830381600087803b15801561071a57600080fd5b505af115801561072e573d6000803e3d6000fd5b50505050610749565b6101e0516001600160a01b0316610360525b6103605160c05160e05160405161075f906109a0565b6001600160a01b03938416815291831660208301529091166040820152606001604051809103906000f08015801561079b573d6000803e3d6000fd5b506001600160a01b039081166103208190526102e0516040516332fd71af60e11b815292166004830152906365fae35e90602401600060405180830381600087803b1580156107e957600080fd5b505af11580156107fd573d6000803e3d6000fd5b505061032051604051639c52a7f160e01b81523360048201526001600160a01b039091169250639c52a7f19150602401600060405180830381600087803b15801561084757600080fd5b505af115801561085b573d6000803e3d6000fd5b5050505060805160a0516102005161010051604051610879906109ad565b6001600160a01b0394851681529284166020840152921660408201526060810191909152608001604051809103906000f0801580156108bc573d6000803e3d6000fd5b506001600160a01b039081166103408190526102e0516040516332fd71af60e11b815292166004830152906365fae35e90602401600060405180830381600087803b15801561090a57600080fd5b505af115801561091e573d6000803e3d6000fd5b505061034051604051639c52a7f160e01b81523360048201526001600160a01b039091169250639c52a7f19150602401600060405180830381600087803b15801561096857600080fd5b505af115801561097c573d6000803e3d6000fd5b5050505050610b58565b610f4c806126cd83390190565b610c548061361983390190565b6118e38061426d83390190565b61239380615b5083390190565b60405161028081016001600160401b03811182821017156109eb57634e487b7160e01b600052604160045260246000fd5b60405290565b80516001600160a01b0381168114610a0857600080fd5b919050565b6000610280828403128015610a2157600080fd5b506000610a2c6109ba565b610a35846109f1565b8152610a43602085016109f1565b6020820152610a54604085016109f1565b6040820152610a65606085016109f1565b6060820152610a76608085016109f1565b608082015260a08481015190820152610a9160c085016109f1565b60c082015260e0848101519082015261010080850151908201526101208085015190820152610ac361014085016109f1565b610140820152610ad661016085016109f1565b610160820152610ae961018085016109f1565b610180820152610afc6101a085016109f1565b6101a08201526101c084810151908201526101e0808501519082015261020080850151908201526102208085015190820152610240808501519082018190529150610b4a61026085016109f1565b610260820152949350505050565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e05161030051610320516103405161036051611892610e3b6000396000818161017d0152818161095e015261163501526000818161029201528181610cbe01528181610d5901528181610df401528181610ec301528181610f6b01528181611008015281816110ae01528181611154015281816111da015281816112610152818161130f0152818161152f01528181611685015261173b0152600081816101c101528181610b9d01528181610c4301528181610ce6015281816116b401526117650152600081816104e50152818161056c0152818161063701528181610776015261165d0152600061047001526000818161050c01526113d50152600081816103fb01526114a10152600081816102b9015261112e0152600081816101e8015261108801526000818161021d0152610fe20152600081816103d40152610f4301526000818161049701528181610e1c01528181611337015281816113fb01526114c70152600081816102e0015261088001526000818161035f015281816115a101526116dc01526000818161042201528181610a2701526117d101526000818161053301528181610c1d015261181301526000818161030701528181610b7701526117f2015260006103ad015260008181610386015261160d0152600081816104be015281816105fd015281816106ca015281816107f4015281816108bf015281816109f401528181610abe015281816112d4015281816113a20152818161146e015281816115df015261178f0152600081816103380152610e9b01526000610449015260008181610244015281816105940152818161065f0152818161070e015261081a01526000818161026b015281816108e50152818161098601528181610a4d01528181610af80152610d8101526118926000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80637b103999116100de578063c11645bc11610097578063c5ce281e11610071578063c5ce281e146104b9578063d741e2f9146104e0578063def8f41b14610507578063fae036d51461052e57600080fd5b8063c11645bc14610444578063c1c0e9c41461046b578063c3b3ad7f1461049257600080fd5b80637b1039991461035a5780637bd2bea7146103815780637dc0d1d0146103a857806396f1b6be146103cf5780639e3ce1cf146103f6578063b56b83531461041d57600080fd5b806339b00e411161013057806339b00e411461028d57806349ed5931146102b4578063533e9bd1146102db578063568d4b6f146103025780636146195414610329578063626cb3c51461033357600080fd5b806301664f661461017857806304bda262146101bc57806313d8c840146101e357806315232515146102185780632e77468d1461023f57806336569e7714610266575b600080fd5b61019f7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61019f7f000000000000000000000000000000000000000000000000000000000000000081565b61020a7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016101b3565b61020a7f000000000000000000000000000000000000000000000000000000000000000081565b61019f7f000000000000000000000000000000000000000000000000000000000000000081565b61019f7f000000000000000000000000000000000000000000000000000000000000000081565b61019f7f000000000000000000000000000000000000000000000000000000000000000081565b61020a7f000000000000000000000000000000000000000000000000000000000000000081565b61019f7f000000000000000000000000000000000000000000000000000000000000000081565b61020a7f000000000000000000000000000000000000000000000000000000000000000081565b610331610555565b005b61019f7f000000000000000000000000000000000000000000000000000000000000000081565b61019f7f000000000000000000000000000000000000000000000000000000000000000081565b61019f7f000000000000000000000000000000000000000000000000000000000000000081565b61019f7f000000000000000000000000000000000000000000000000000000000000000081565b61019f7f000000000000000000000000000000000000000000000000000000000000000081565b61020a7f000000000000000000000000000000000000000000000000000000000000000081565b61020a7f000000000000000000000000000000000000000000000000000000000000000081565b61019f7f000000000000000000000000000000000000000000000000000000000000000081565b61019f7f000000000000000000000000000000000000000000000000000000000000000081565b61019f7f000000000000000000000000000000000000000000000000000000000000000081565b61020a7f000000000000000000000000000000000000000000000000000000000000000081565b61019f7f000000000000000000000000000000000000000000000000000000000000000081565b61020a7f000000000000000000000000000000000000000000000000000000000000000081565b61020a7f000000000000000000000000000000000000000000000000000000000000000081565b6040516332fd71af60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000016906365fae35e90602401600060405180830381600087803b1580156105d857600080fd5b505af11580156105ec573d6000803e3d6000fd5b505060405163ebecb39d60e01b81527f000000000000000000000000000000000000000000000000000000000000000060048201526207069760ec1b60248201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660448301527f000000000000000000000000000000000000000000000000000000000000000016925063ebecb39d9150606401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b5050604051630d05943f60e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152621b585d60ea1b60248201526b033b2e3c9fd0803ce800000060448201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169250631a0b287e9150606401600060405180830381600087803b15801561075c57600080fd5b505af1158015610770573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663181783586040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156107cf57600080fd5b505af11580156107e3573d6000803e3d6000fd5b5050604051631504460f60e01b81527f000000000000000000000000000000000000000000000000000000000000000060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169250631504460f9150602401600060405180830381600087803b15801561086857600080fd5b505af115801561087c573d6000803e3d6000fd5b50507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031691506109e5905057604051633b66319560e01b81527f000000000000000000000000000000000000000000000000000000000000000060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690633b66319590602401600060405180830381600087803b15801561093157600080fd5b505af1158015610945573d6000803e3d6000fd5b50506040516332fd71af60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f00000000000000000000000000000000000000000000000000000000000000001692506365fae35e9150602401600060405180830381600087803b1580156109cc57600080fd5b505af11580156109e0573d6000803e3d6000fd5b505050505b604051630d05943f60e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152636c696e6560e01b60248201527f000000000000000000000000000000000000000000000000000000000000000060448201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690631a0b287e90606401600060405180830381600087803b158015610a9957600080fd5b505af1158015610aad573d6000803e3d6000fd5b5050604051630d05943f60e11b81527f0000000000000000000000000000000000000000000000000000000000000000600482015263191d5cdd60e21b6024820152600060448201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169250631a0b287e9150606401600060405180830381600087803b158015610b4657600080fd5b505af1158015610b5a573d6000803e3d6000fd5b5050604051630a6ba04560e21b8152623a34b760e91b60048201527f000000000000000000000000000000000000000000000000000000000000000060248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031692506329ae81149150604401600060405180830381600087803b158015610beb57600080fd5b505af1158015610bff573d6000803e3d6000fd5b5050604051630a6ba04560e21b8152631d1bdd5d60e21b60048201527f000000000000000000000000000000000000000000000000000000000000000060248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031692506329ae81149150604401600060405180830381600087803b158015610c9157600080fd5b505af1158015610ca5573d6000803e3d6000fd5b50506040516328ec8bf160e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000016925063a3b22fc49150602401600060405180830381600087803b158015610d2c57600080fd5b505af1158015610d40573d6000803e3d6000fd5b50506040516332fd71af60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f00000000000000000000000000000000000000000000000000000000000000001692506365fae35e9150602401600060405180830381600087803b158015610dc757600080fd5b505af1158015610ddb573d6000803e3d6000fd5b50506040516332fd71af60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f00000000000000000000000000000000000000000000000000000000000000001692506365fae35e9150602401600060405180830381600087803b158015610e6257600080fd5b505af1158015610e76573d6000803e3d6000fd5b505060405163d4e8be8360e01b815262766f7760e81b60048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660248301527f000000000000000000000000000000000000000000000000000000000000000016925063d4e8be839150604401600060405180830381600087803b158015610f0957600080fd5b505af1158015610f1d573d6000803e3d6000fd5b505060405163d4e8be8360e01b81526363616c6360e01b60048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660248301527f000000000000000000000000000000000000000000000000000000000000000016925063d4e8be839150604401600060405180830381600087803b158015610fb157600080fd5b505af1158015610fc5573d6000803e3d6000fd5b5050604051630a6ba04560e21b815262313ab360e91b60048201527f000000000000000000000000000000000000000000000000000000000000000060248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031692506329ae81149150604401600060405180830381600087803b15801561105657600080fd5b505af115801561106a573d6000803e3d6000fd5b5050604051630a6ba04560e21b8152631d185a5b60e21b60048201527f000000000000000000000000000000000000000000000000000000000000000060248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031692506329ae81149150604401600060405180830381600087803b1580156110fc57600080fd5b505af1158015611110573d6000803e3d6000fd5b5050604051630a6ba04560e21b8152630637573760e41b60048201527f000000000000000000000000000000000000000000000000000000000000000060248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031692506329ae81149150604401600060405180830381600087803b1580156111a257600080fd5b505af11580156111b6573d6000803e3d6000fd5b5050604051630a6ba04560e21b81526207469760ec1b6004820152600060248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031692506329ae81149150604401600060405180830381600087803b15801561122857600080fd5b505af115801561123c573d6000803e3d6000fd5b5050604051630a6ba04560e21b8152630636869760e41b6004820152600060248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031692506329ae81149150604401600060405180830381600087803b1580156112af57600080fd5b505af11580156112c3573d6000803e3d6000fd5b505060405163ebecb39d60e01b81527f00000000000000000000000000000000000000000000000000000000000000006004820152630636c69760e41b60248201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660448301527f000000000000000000000000000000000000000000000000000000000000000016925063ebecb39d9150606401600060405180830381600087803b15801561137d57600080fd5b505af1158015611391573d6000803e3d6000fd5b5050604051630d05943f60e11b81527f0000000000000000000000000000000000000000000000000000000000000000600482015263063686f760e41b60248201527f000000000000000000000000000000000000000000000000000000000000000060448201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169250631a0b287e9150606401600060405180830381600087803b15801561144957600080fd5b505af115801561145d573d6000803e3d6000fd5b5050604051630d05943f60e11b81527f0000000000000000000000000000000000000000000000000000000000000000600482015263686f6c6560e01b60248201527f000000000000000000000000000000000000000000000000000000000000000060448201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169250631a0b287e9150606401600060405180830381600087803b15801561151557600080fd5b505af1158015611529573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630cbb58626040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561158857600080fd5b505af115801561159c573d6000803e3d6000fd5b5050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615905061173957604051631c79c0e560e11b81527f000000000000000000000000000000000000000000000000000000000000000060048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660248301527f0000000000000000000000000000000000000000000000000000000000000000811660448301527f0000000000000000000000000000000000000000000000000000000000000000811660648301527f000000000000000000000000000000000000000000000000000000000000000081166084830152600060a48301527f0000000000000000000000000000000000000000000000000000000000000000811660c48301527f000000000000000000000000000000000000000000000000000000000000000016906338f381ca9060e401600060405180830381600087803b15801561172057600080fd5b505af1158015611734573d6000803e3d6000fd5b505050505b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000007f2ed482f800439d546a30151101b134d6ca228c9f42e16973982b4e8dd20043ef7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000604051611852939291909283526020830191909152604082015260600190565b60405180910390a456fea2646970667358221220ebe98196d45d11812e12314096223cab8700527c761efc7346cb77059f1c409c64736f6c634300081c003360e060405234801561001057600080fd5b50604051610f4c380380610f4c83398101604081905261002f91610281565b6001600160a01b03808316608052811660a08190526040805163313ce56760e01b815290516000929163313ce5679160048083019260209291908290030181865afa158015610082573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100a691906102b4565b905060128160ff16111561010b5760405162461bcd60e51b815260206004820152602260248201527f5069704a6f696e2f756e737570706f727465642d646563696d616c732d67742d604482015261062760f31b606482015260840160405180910390fd5b60ff811660c0526706f05b59d3b200006004556ec097ce7bc90715b34b9f1000000000600555670d2f13f7789f0000600655600280546001600160a01b03191633179055604080518082019091528061016d670de0b6b3a764000060016102de565b8152600060209182018190528251905501516001805460ff19169115159190911781557f282f5690f036ef4ea4bac95238e731bbb4d05f746b72df99dd740cef482259a6906101c590670de0b6b3a7640000906102de565b60408051918252600060208301520160405180910390a17f91a88a19f6ef384ea8f15e06b9139c98fc19dcbd91a4ba2d218ac43cee29522760045460055460405161021a929190918252602082015260400190565b60405180910390a17fa7a696c280d1b8a49f1f616aaed7fc30ca8ffad2b5de0fa2ca17fbdde2ba940c60065460405161025591815260200190565b60405180910390a1505050610309565b80516001600160a01b038116811461027c57600080fd5b919050565b6000806040838503121561029457600080fd5b61029d83610265565b91506102ab60208401610265565b90509250929050565b6000602082840312156102c657600080fd5b815160ff811681146102d757600080fd5b9392505050565b808202811582820484141761030357634e487b7160e01b600052601160045260246000fd5b92915050565b60805160a05160c051610bff61034d6000396000818161027501526107df0152600081816102e6015261081d015260008181610233015261084f0152610bff6000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c80636f265b93116100b8578063b3bcfa821161007c578063b3bcfa8214610270578063b8fea0a1146102a9578063cf3dd5d5146102b2578063d18d7d89146102bb578063f29c29c4146102ce578063fc0c546a146102e157600080fd5b80636f265b93146102155780637c5e2795146102265780637dc0d1d01461022e5780638efbc0d81461025557806398d5fdca1461026857600080fd5b806355d6c710116100ff57806355d6c710146101b257806357de26a4146101dd57806359e02dd7146101e557806365c4ce7a146101f35780636a1460241461020657600080fd5b80630e5a6c701461013c578063181783581461015e57806319b9dfb514610168578063406953631461017b5780634fce7a2a14610192575b600080fd5b610144610308565b604080519283529015156020830152015b60405180910390f35b6101666103f3565b005b6101666101763660046109b9565b6105ab565b61018460065481565b604051908152602001610155565b6101846101a03660046109db565b60036020526000908152604090205481565b6002546101c5906001600160a01b031681565b6040516001600160a01b039091168152602001610155565b610184610669565b60005460015460ff16610144565b6101666102013660046109db565b6106bd565b610184670de0b6b3a764000081565b600054600154610144919060ff1682565b610184610701565b6101c57f000000000000000000000000000000000000000000000000000000000000000081565b610166610263366004610a0b565b610717565b6101446107d4565b6102977f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff9091168152602001610155565b61018460045481565b61018460055481565b6101666102c93660046109db565b610926565b6101666102dc3660046109db565b610972565b6101c57f000000000000000000000000000000000000000000000000000000000000000081565b33600090815260036020526040812054819060011461036e5760405162461bcd60e51b815260206004820152601760248201527f5069704a6f696e2f6e6f742d77686974656c697374656400000000000000000060448201526064015b60405180910390fd5b600080306001600160a01b03166398d5fdca6040518163ffffffff1660e01b81526004016040805180830381865afa1580156103ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d29190610a24565b91509150806103e55760008054906103e9565b8160015b9350935050509091565b306001600160a01b03166398d5fdca6040518163ffffffff1660e01b81526004016040805180830381865afa92505050801561044c575060408051601f3d908101601f1916820190925261044991810190610a24565b60015b6104a0576001805460ff19169055600080546040517f282f5690f036ef4ea4bac95238e731bbb4d05f746b72df99dd740cef482259a6926104969282521515602082015260400190565b60405180910390a1565b801580156104ae5750600082115b156105015760045460055460408051858152600060208201529081019290925260608201527fd19f98d3aaca020119e9fe2da189c760b3488c9f588e2435e7bda3d8d96fa3689060800160405180910390a15b801561056557604080518082018252838152600160209182018190526000859055805460ff1916811781558251858152918201527f282f5690f036ef4ea4bac95238e731bbb4d05f746b72df99dd740cef482259a691015b60405180910390a15050565b6001805460ff19169055600080546040517f282f5690f036ef4ea4bac95238e731bbb4d05f746b72df99dd740cef482259a6926105599282521515602082015260400190565b6002546001600160a01b031633146105d55760405162461bcd60e51b815260040161036590610a5a565b6000821180156105e457508181115b6106295760405162461bcd60e51b81526020600482015260166024820152755069704a6f696e2f696e76616c69642d626f756e647360501b6044820152606401610365565b6004829055600581905560408051838152602081018390527f91a88a19f6ef384ea8f15e06b9139c98fc19dcbd91a4ba2d218ac43cee2952279101610559565b60015460009060ff166106b65760405162461bcd60e51b81526020600482015260156024820152745069704a6f696e2f696e76616c69642d707269636560581b6044820152606401610365565b5060005490565b6002546001600160a01b031633146106e75760405162461bcd60e51b815260040161036590610a5a565b6001600160a01b0316600090815260036020526040812055565b610714670de0b6b3a76400006001610aa0565b81565b6002546001600160a01b031633146107415760405162461bcd60e51b815260040161036590610a5a565b670de0b6b3a76400008111156107995760405162461bcd60e51b815260206004820152601d60248201527f5069704a6f696e2f666c6f6f722d63616e6e6f742d6578636565642d310000006044820152606401610365565b60068190556040518181527fa7a696c280d1b8a49f1f616aaed7fc30ca8ffad2b5de0fa2ca17fbdde2ba940c9060200160405180910390a150565b6000808061080660ff7f000000000000000000000000000000000000000000000000000000000000000016600a610ba4565b60405163d0578a0160e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018390529192507f00000000000000000000000000000000000000000000000000000000000000009091169063d0578a0190604401602060405180830381865afa9250505080156108b4575060408051601f3d908101601f191682019092526108b191810190610bb0565b60015b6108c357506000928392509050565b806000036108d75750600093849350915050565b60065481908110156108ea5750806108f5565b50670de0b6b3a76400005b6000600454821015801561090b57506005548211155b90508061091957600061091b565b815b969095509350505050565b6002546001600160a01b031633146109505760405162461bcd60e51b815260040161036590610a5a565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b0316331461099c5760405162461bcd60e51b815260040161036590610a5a565b6001600160a01b0316600090815260036020526040902060019055565b600080604083850312156109cc57600080fd5b50508035926020909101359150565b6000602082840312156109ed57600080fd5b81356001600160a01b0381168114610a0457600080fd5b9392505050565b600060208284031215610a1d57600080fd5b5035919050565b60008060408385031215610a3757600080fd5b825160208401519092508015158114610a4f57600080fd5b809150509250929050565b602080825260169082015275141a5c129bda5b8bdb9bdd0b585d5d1a1bdc9a5e995960521b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610ab757610ab7610a8a565b92915050565b6001815b6001841115610af857808504811115610adc57610adc610a8a565b6001841615610aea57908102905b60019390931c928002610ac1565b935093915050565b600082610b0f57506001610ab7565b81610b1c57506000610ab7565b8160018114610b325760028114610b3c57610b58565b6001915050610ab7565b60ff841115610b4d57610b4d610a8a565b50506001821b610ab7565b5060208310610133831016604e8410600b8410161715610b7b575081810a610ab7565b610b886000198484610abd565b8060001904821115610b9c57610b9c610a8a565b029392505050565b6000610a048383610b00565b600060208284031215610bc257600080fd5b505191905056fea26469706673582212203d49134546954b6a36d2355e74e77f2ee69cb8f428f0f228486a17276f45ac0864736f6c634300081c0033608060405234801561001057600080fd5b50604051610c54380380610c5483398101604081905261002f916101a9565b3360009081526020818152604091829020600190819055600481815581546001600160a01b038881166001600160a01b0319928316179093556002879055600380549387169390911683179055835163313ce56760e01b81529351919363313ce5679381830193909290918290030181865afa1580156100b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100d791906101e5565b6003805460ff60a01b1916600160a01b60ff9384168102919091179182905560129104909116111561015a5760405162461bcd60e51b815260206004820152602260248201527f47656d4a6f696e2f756e737570706f727465642d646563696d616c732d67742d604482015261062760f31b606482015260840160405180910390fd5b60405133907fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a6090600090a250505061020f565b80516001600160a01b03811681146101a457600080fd5b919050565b6000806000606084860312156101be57600080fd5b6101c78461018d565b9250602084015191506101dc6040850161018d565b90509250925092565b6000602082840312156101f757600080fd5b815160ff8116811461020857600080fd5b9392505050565b610a368061021e6000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c8063957aa58c11610071578063957aa58c146101215780639c52a7f114610138578063b3bcfa821461014b578063bf353dbb14610171578063c5ce281e14610191578063ef693bed1461019a57600080fd5b806336569e77146100ae5780633b4da69f146100de57806365fae35e146100f357806369245009146101065780637bd2bea71461010e575b600080fd5b6001546100c1906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100f16100ec3660046107e2565b6101ad565b005b6100f161010136600461080c565b61041c565b6100f1610490565b6003546100c1906001600160a01b031681565b61012a60045481565b6040519081526020016100d5565b6100f161014636600461080c565b6104ef565b60035461015f90600160a01b900460ff1681565b60405160ff90911681526020016100d5565b61012a61017f36600461080c565b60006020819052908152604090205481565b61012a60025481565b6100f16101a83660046107e2565b610562565b6004546001146101f75760405162461bcd60e51b815260206004820152601060248201526f47656d4a6f696e2f6e6f742d6c69766560801b60448201526064015b60405180910390fd5b60035460009061021290600160a01b900460ff166012610844565b61021d90600a61094a565b6102279083610959565b600354909150829061024490600160a01b900460ff166012610844565b61024f90600a61094a565b6102599083610970565b146102a25760405162461bcd60e51b815260206004820152601960248201527847656d4a6f696e2f6f766572666c6f772d6f6e2d7363616c6560381b60448201526064016101ee565b600154600254604051633e6e9fef60e11b815260048101919091526001600160a01b0385811660248301526044820184905290911690637cdd3fde90606401600060405180830381600087803b1580156102fb57600080fd5b505af115801561030f573d6000803e3d6000fd5b50506003546040516323b872dd60e01b8152336004820152306024820152604481018690526001600160a01b0390911692506323b872dd91506064016020604051808303816000875af115801561036a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038e9190610992565b6103d45760405162461bcd60e51b815260206004820152601760248201527623b2b6a537b4b717b330b4b632b216ba3930b739b332b960491b60448201526064016101ee565b826001600160a01b03167fb4e09949657f21548b58afe74e7b86cd2295da5ff1598ae1e5faecb1cf19ca958360405161040f91815260200190565b60405180910390a2505050565b3360009081526020819052604090205460011461044b5760405162461bcd60e51b81526004016101ee906109b4565b6001600160a01b03811660008181526020819052604080822060019055517fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a609190a250565b336000908152602081905260409020546001146104bf5760405162461bcd60e51b81526004016101ee906109b4565b600060048190556040517f2308ed18a14e800c39b86eb6ea43270105955ca385b603b64eca89f98ae8fbda9190a1565b3360009081526020819052604090205460011461051e5760405162461bcd60e51b81526004016101ee906109b4565b6001600160a01b038116600081815260208190526040808220829055517f184450df2e323acec0ed3b5c7531b81f9b4cdef7914dfd4c0a4317416bb5251b9190a250565b6004546001146105a75760405162461bcd60e51b815260206004820152601060248201526f47656d4a6f696e2f6e6f742d6c69766560801b60448201526064016101ee565b6003546000906105c290600160a01b900460ff166012610844565b6105cd90600a61094a565b90506105e0816001600160ff1b03610970565b82111561062b5760405162461bcd60e51b815260206004820152601960248201527847656d4a6f696e2f6f766572666c6f772d6f6e2d7363616c6560381b60448201526064016101ee565b60006106378284610959565b6001546002549192506001600160a01b031690637cdd3fde903361065a856109e4565b6040516001600160e01b031960e086901b16815260048101939093526001600160a01b0390911660248301526044820152606401600060405180830381600087803b1580156106a857600080fd5b505af11580156106bc573d6000803e3d6000fd5b505060035460405163a9059cbb60e01b81526001600160a01b03888116600483015260248201889052909116925063a9059cbb91506044016020604051808303816000875af1158015610713573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107379190610992565b61077d5760405162461bcd60e51b815260206004820152601760248201527623b2b6a537b4b717b330b4b632b216ba3930b739b332b960491b60448201526064016101ee565b836001600160a01b03167f22d324652c93739755cf4581508b60875ebdd78c20c0cff5cf8e23452b299631846040516107b891815260200190565b60405180910390a250505050565b80356001600160a01b03811681146107dd57600080fd5b919050565b600080604083850312156107f557600080fd5b6107fe836107c6565b946020939093013593505050565b60006020828403121561081e57600080fd5b610827826107c6565b9392505050565b634e487b7160e01b600052601160045260246000fd5b60ff828116828216039081111561085d5761085d61082e565b92915050565b6001815b600184111561089e578085048111156108825761088261082e565b600184161561089057908102905b60019390931c928002610867565b935093915050565b6000826108b55750600161085d565b816108c25750600061085d565b81600181146108d857600281146108e2576108fe565b600191505061085d565b60ff8411156108f3576108f361082e565b50506001821b61085d565b5060208310610133831016604e8410600b8410161715610921575081810a61085d565b61092e6000198484610863565b80600019048211156109425761094261082e565b029392505050565b600061082760ff8416836108a6565b808202811582820484141761085d5761085d61082e565b60008261098d57634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156109a457600080fd5b8151801515811461082757600080fd5b60208082526016908201527511d95b529bda5b8bdb9bdd0b585d5d1a1bdc9a5e995960521b604082015260600190565b6000600160ff1b82016109f9576109f961082e565b506000039056fea264697066735822122057880ce88c4c9b49af9b018b5491112feb7f9be0e4a10eb7c8384f2e7a7dcbcc64736f6c634300081c0033610180604052600160035534801561001657600080fd5b506040516118e33803806118e383398101604081905261003591610606565b3360008181526020819052604080822060019055517fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a609190a26001600160a01b0380841660c08190528382166101205290821661014052604080516336569e7760e01b815290516336569e77916004808201926020929091908290030181865afa1580156100c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100eb9190610649565b6001600160a01b031660a0816001600160a01b031681525050826001600160a01b0316637bd2bea76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610142573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101669190610649565b6001600160a01b031660e0816001600160a01b031681525050816001600160a01b031663f4b9fa756040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e19190610649565b6001600160a01b0316610100816001600160a01b031681525050826001600160a01b031663c5ce281e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610239573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025d919061066b565b608081815250506000836001600160a01b031663b3bcfa826040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c89190610684565b905060128160ff1611156103235760405162461bcd60e51b815260206004820152601960248201527f50534d2f67656d2d646563696d616c732d746f6f2d686967680000000000000060448201526064015b60405180910390fd5b61032e8160126106bd565b61033990600a6107c3565b610160526101005160405163095ea7b360e01b81526001600160a01b03858116600483015260001960248301529091169063095ea7b3906044016020604051808303816000875af1158015610392573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103b691906107d2565b6104025760405162461bcd60e51b815260206004820152601660248201527f50534d2f6461692d617070726f76652d6661696c656400000000000000000000604482015260640161031a565b60e05160405163095ea7b360e01b81526001600160a01b03868116600483015260001960248301529091169063095ea7b3906044016020604051808303816000875af1158015610456573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061047a91906107d2565b6104c65760405162461bcd60e51b815260206004820152601660248201527f50534d2f67656d2d617070726f76652d6661696c656400000000000000000000604482015260640161031a565b60a0516040516328ec8bf160e21b81526001600160a01b0385811660048301529091169063a3b22fc490602401600060405180830381600087803b15801561050d57600080fd5b505af1158015610521573d6000803e3d6000fd5b505060a0516040516328ec8bf160e21b81526001600160a01b038881166004830152909116925063a3b22fc49150602401600060405180830381600087803b15801561056c57600080fd5b505af1158015610580573d6000803e3d6000fd5b505060a0516040516328ec8bf160e21b81523060048201526001600160a01b03909116925063a3b22fc49150602401600060405180830381600087803b1580156105c957600080fd5b505af11580156105dd573d6000803e3d6000fd5b50505050505050506107f4565b80516001600160a01b038116811461060157600080fd5b919050565b60008060006060848603121561061b57600080fd5b610624846105ea565b9250610632602085016105ea565b9150610640604085016105ea565b90509250925092565b60006020828403121561065b57600080fd5b610664826105ea565b9392505050565b60006020828403121561067d57600080fd5b5051919050565b60006020828403121561069657600080fd5b815160ff8116811461066457600080fd5b634e487b7160e01b600052601160045260246000fd5b60ff82811682821603908111156106d6576106d66106a7565b92915050565b6001815b6001841115610717578085048111156106fb576106fb6106a7565b600184161561070957908102905b60019390931c9280026106e0565b935093915050565b60008261072e575060016106d6565b8161073b575060006106d6565b8160018114610751576002811461075b57610777565b60019150506106d6565b60ff84111561076c5761076c6106a7565b50506001821b6106d6565b5060208310610133831016604e8410600b841016171561079a575081810a6106d6565b6107a760001984846106dc565b80600019048211156107bb576107bb6106a7565b029392505050565b600061066460ff84168361071f565b6000602082840312156107e457600080fd5b8151801515811461066457600080fd5b60805160a05160c05160e0516101005161012051610140516101605161100c6108d7600039600081816101b60152818161053101526109030152600081816101f4015281816107ce0152610af60152600081816102d2015281816105d30152610bb8015260008181610333015261059001526000818161023601526109620152600081816101360152818161073e01526109a501526000818161018f015281816106390152818161079e01528181610a5e01528181610ac601528181610d180152610dc60152600081816102f9015281816106680152610a16015261100c6000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c8063957aa58c116100ad578063c11645bc11610071578063c11645bc146102cd578063c5ce281e146102f4578063dc4d20fa1461031b578063f4b9fa751461032e578063fae036d51461035557600080fd5b8063957aa58c1461026b57806395991276146102745780639c52a7f114610287578063a3b22fc41461029a578063bf353dbb146102ad57600080fd5b8063626cb3c5116100f4578063626cb3c5146101ef57806365fae35e1461021657806369245009146102295780637bd2bea7146102315780638d7ef9bb1461025857600080fd5b806301664f661461013157806329ae81141461017557806336569e771461018a5780634010f777146101b1578063568d4b6f146101e6575b600080fd5b6101587f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b610188610183366004610e93565b61035e565b005b6101587f000000000000000000000000000000000000000000000000000000000000000081565b6101d87f000000000000000000000000000000000000000000000000000000000000000081565b60405190815260200161016c565b6101d860015481565b6101587f000000000000000000000000000000000000000000000000000000000000000081565b610188610224366004610ed1565b610413565b610188610487565b6101587f000000000000000000000000000000000000000000000000000000000000000081565b610188610266366004610ef3565b6104e6565b6101d860035481565b610188610282366004610ef3565b6108b8565b610188610295366004610ed1565b610c57565b6101886102a8366004610ed1565b610cca565b6101d86102bb366004610ed1565b60006020819052908152604090205481565b6101587f000000000000000000000000000000000000000000000000000000000000000081565b6101d87f000000000000000000000000000000000000000000000000000000000000000081565b610188610329366004610ed1565b610d78565b6101587f000000000000000000000000000000000000000000000000000000000000000081565b6101d860025481565b33600090815260208190526040812054900361038d5760405163ea8e4eb560e01b815260040160405180910390fd5b81623a34b760e91b036103a45760018190556103d5565b81631d1bdd5d60e21b036103bc5760028190556103d5565b604051633494a40d60e21b815260040160405180910390fd5b817fe986e40cc8c151830d4f61050f4fb2e4add8567caad2d5f5496f9158e91fe4c78260405161040791815260200190565b60405180910390a25050565b3360009081526020819052604081205490036104425760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b03811660008181526020819052604080822060019055517fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a609190a250565b3360009081526020819052604081205490036104b65760405163ea8e4eb560e01b815260040160405180910390fd5b600060038190556040517f2308ed18a14e800c39b86eb6ea43270105955ca385b603b64eca89f98ae8fbda9190a1565b60035460000361050957604051634174f77b60e01b815260040160405180910390fd5b8060000361052a57604051631f2a200560e01b815260040160405180910390fd5b60006105567f000000000000000000000000000000000000000000000000000000000000000083610f33565b90506000670de0b6b3a7640000600254836105719190610f33565b61057b9190610f50565b905060006105898284610f72565b90506105b77f0000000000000000000000000000000000000000000000000000000000000000333084610df5565b604051633b4da69f60e01b8152306004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690633b4da69f90604401600060405180830381600087803b15801561061f57600080fd5b505af1158015610633573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663760887037f00000000000000000000000000000000000000000000000000000000000000003030308861069490610f85565b61069d8a610f85565b6040516001600160e01b031960e089901b16815260048101969096526001600160a01b039485166024870152928416604486015292166064840152608483019190915260a482015260c401600060405180830381600087803b15801561070257600080fd5b505af1158015610716573d6000803e3d6000fd5b505060405163ef693bed60e01b81526001600160a01b038881166004830152602482018890527f000000000000000000000000000000000000000000000000000000000000000016925063ef693bed9150604401600060405180830381600087803b15801561078457600080fd5b505af1158015610798573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663bb35783b307f0000000000000000000000000000000000000000000000000000000000000000856b033b2e3c9fd0803ce80000006108059190610f33565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b15801561085457600080fd5b505af1158015610868573d6000803e3d6000fd5b505060408051878152602081018690526001600160a01b03891693507f085d06ecf4c34b237767a31c0888e121d89546a77f186f1987c6b8715e1a8caa9250015b60405180910390a25050505050565b6003546000036108db57604051634174f77b60e01b815260040160405180910390fd5b806000036108fc57604051631f2a200560e01b815260040160405180910390fd5b60006109287f000000000000000000000000000000000000000000000000000000000000000083610f33565b90506000670de0b6b3a7640000600154836109439190610f33565b61094d9190610f50565b9050600061095b8284610fa1565b90506109897f0000000000000000000000000000000000000000000000000000000000000000333087610df5565b604051633b4da69f60e01b8152306004820152602481018590527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690633b4da69f90604401600060405180830381600087803b1580156109f157600080fd5b505af1158015610a05573d6000803e3d6000fd5b5050604051637608870360e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015230602482018190526044820181905260648201526084810186905260a481018690527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031692506376088703915060c401600060405180830381600087803b158015610aac57600080fd5b505af1158015610ac0573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663bb35783b307f0000000000000000000000000000000000000000000000000000000000000000856b033b2e3c9fd0803ce8000000610b2d9190610f33565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b158015610b7c57600080fd5b505af1158015610b90573d6000803e3d6000fd5b505060405163ef693bed60e01b81526001600160a01b038881166004830152602482018590527f000000000000000000000000000000000000000000000000000000000000000016925063ef693bed9150604401600060405180830381600087803b158015610bfe57600080fd5b505af1158015610c12573d6000803e3d6000fd5b505060408051878152602081018690526001600160a01b03891693507fef75f5a47cc9a929968796ceb84f19e7541617b4577f2c228ea95200e15720819250016108a9565b336000908152602081905260408120549003610c865760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b038116600081815260208190526040808220829055517f184450df2e323acec0ed3b5c7531b81f9b4cdef7914dfd4c0a4317416bb5251b9190a250565b336000908152602081905260408120549003610cf95760405163ea8e4eb560e01b815260040160405180910390fd5b6040516328ec8bf160e21b81526001600160a01b0382811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063a3b22fc4906024015b600060405180830381600087803b158015610d5d57600080fd5b505af1158015610d71573d6000803e3d6000fd5b5050505050565b336000908152602081905260408120549003610da75760405163ea8e4eb560e01b815260040160405180910390fd5b604051636e26907d60e11b81526001600160a01b0382811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063dc4d20fa90602401610d43565b6040516323b872dd60e01b81526001600160a01b0384811660048301528381166024830152604482018390528516906323b872dd906064016020604051808303816000875af1158015610e4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e709190610fb4565b610e8d576040516312171d8360e31b815260040160405180910390fd5b50505050565b60008060408385031215610ea657600080fd5b50508035926020909101359150565b80356001600160a01b0381168114610ecc57600080fd5b919050565b600060208284031215610ee357600080fd5b610eec82610eb5565b9392505050565b60008060408385031215610f0657600080fd5b610f0f83610eb5565b946020939093013593505050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610f4a57610f4a610f1d565b92915050565b600082610f6d57634e487b7160e01b600052601260045260246000fd5b500490565b80820180821115610f4a57610f4a610f1d565b6000600160ff1b8201610f9a57610f9a610f1d565b5060000390565b81810381811115610f4a57610f4a610f1d565b600060208284031215610fc657600080fd5b81518015158114610eec57600080fdfea26469706673582212205d9ad6714ce9c2b227deb24c4a848355b353f719cadeb885d144d6c2884be63664736f6c634300081c003360c06040526000600e5534801561001557600080fd5b50604051612393380380612393833981016040819052610034916100de565b6001600160a01b0384811660a052600380546001600160a01b0319908116868416179091556001805490911691841691909117815560808290526b033b2e3c9fd0803ce80000006005553360008181526020819052604080822093909355915190917fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a6091a250505050610129565b80516001600160a01b03811681146100d957600080fd5b919050565b600080600080608085870312156100f457600080fd5b6100fd856100c2565b935061010b602086016100c2565b9250610119604086016100c2565b6060959095015193969295505050565b60805160a0516121d56101be600039600081816102a4015281816105210152818161085901528181610db701528181610e2e01528181610f1c0152818161108a015281816113f501526118ee015260008181610498015281816104f8015281816105a60152818161078d0152818161081f01528181610d7101528181610f8b015281816110470152611c3301526121d56000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c806375f12b2111610104578063b61500e4116100a2578063c5ce281e11610071578063c5ce281e14610493578063cfdd3302146104ba578063d4e8be83146104c3578063d843416d146104d657600080fd5b8063b61500e41461042a578063ba2cdc7514610457578063bf353dbb14610460578063c3b3ad7f1461048057600080fd5b8063898eb267116100de578063898eb2671461035957806396f1b6be1461036c5780639c52a7f11461037f578063b5f522f71461039257600080fd5b806375f12b211461032a5780638033d5811461033357806381a794cb1461034657600080fd5b806329ae81141161017157806349ed59311161014b57806349ed5931146102c65780635c622a0e146102cf578063626cb3c51461030457806365fae35e1461031757600080fd5b806329ae8114146102615780632e77468d1461027457806336569e771461029f57600080fd5b806313d8c840116101ad57806313d8c8401461020a578063152325151461021357806326e027f11461021c5780632755cd2d1461022f57600080fd5b806306661abd146101d45780630cbb5862146101eb5780630f560cd7146101f5575b600080fd5b600b545b6040519081526020015b60405180910390f35b6101f36104e9565b005b6101fd61067f565b6040516101e29190611e11565b6101d860065481565b6101d860055481565b6101f361022a366004611e54565b6106d7565b60085461024990600160401b90046001600160c01b031681565b6040516001600160c01b0390911681526020016101e2565b6101f361026f366004611e6d565b6108fa565b600354610287906001600160a01b031681565b6040516001600160a01b0390911681526020016101e2565b6102877f000000000000000000000000000000000000000000000000000000000000000081565b6101d860075481565b6102e26102dd366004611e54565b610a74565b60408051941515855260208501939093529183015260608201526080016101e2565b600254610287906001600160a01b031681565b6101f3610325366004611ea7565b610afd565b6101d8600e5481565b6101d8610341366004611e54565b610b72565b6101f3610354366004611ec4565b610b93565b6101d8610367366004611f68565b61117a565b600454610287906001600160a01b031681565b6101f361038d366004611ea7565b61151d565b6103eb6103a0366004611e54565b600c60205260009081526040902080546001820154600283015460038401546004909401549293919290916001600160a01b03811691600160a01b9091046001600160601b03169086565b604080519687526020870195909552938501929092526001600160a01b031660608401526001600160601b0316608083015260a082015260c0016101e2565b60085461043e9067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016101e2565b6101d860095481565b6101d861046e366004611ea7565b60006020819052908152604090205481565b600154610287906001600160a01b031681565b6101d87f000000000000000000000000000000000000000000000000000000000000000081565b6101d8600a5481565b6101f36104d1366004611fb2565b611591565b6101f36104e4366004611fb2565b6116da565b604051636cb1c69b60e11b81527f000000000000000000000000000000000000000000000000000000000000000060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063d9638d369060240160a060405180830381865afa158015610570573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105949190611fe2565b600154604051631af24ca760e31b81527f00000000000000000000000000000000000000000000000000000000000000006004820152919650670de0b6b3a764000095506001600160a01b0316935063d792653892506024019050602060405180830381865afa15801561060c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106309190612022565b61063a9083612051565b610644919061206e565b60098190556040519081527f55fdb012a699c045403977212c8fc12fd6d1642fa30eac085dc592c29077ce059060200160405180910390a150565b6060600b8054806020026020016040519081016040528092919081815260200182805480156106cd57602002820191906000526020600020905b8154815260200190600101908083116106b9575b5050505050905090565b336000908152602081905260409020546001146107075760405163ea8e4eb560e01b815260040160405180910390fd5b600d5460010361072a576040516305fb981560e51b815260040160405180910390fd5b6001600d556000818152600c60205260409020600301546001600160a01b03166107675760405163cc16557d60e01b815260040160405180910390fd5b600180546000838152600c60205260409081902090920154915163321c64fd60e21b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260248101929092526001600160a01b03169063c87193f490604401600060405180830381600087803b1580156107e657600080fd5b505af11580156107fa573d6000803e3d6000fd5b5050506000828152600c602052604090819020600201549051633088df1760e11b81527f0000000000000000000000000000000000000000000000000000000000000000600482015230602482015233604482015260648101919091527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169150636111be2e90608401600060405180830381600087803b1580156108a657600080fd5b505af11580156108ba573d6000803e3d6000fd5b505050506108c781611a86565b60405181907f2c5d2826eb5903b8fc201cf48094b858f42f61c7eaac9aaf43ebed490138144e90600090a2506000600d55565b3360009081526020819052604090205460011461092a5760405163ea8e4eb560e01b815260040160405180910390fd5b600d5460010361094d576040516305fb981560e51b815260040160405180910390fd5b6001600d5562313ab360e91b82900361096a576005819055610a31565b81631d185a5b60e21b03610982576006819055610a31565b81630637573760e41b0361099a576007819055610a31565b81630636869760e41b036109ca576008805467ffffffffffffffff191667ffffffffffffffff8316179055610a31565b816207469760ec1b036109fd576008805467ffffffffffffffff16600160401b6001600160c01b03841602179055610a31565b81661cdd1bdc1c195960ca1b03610a1857600e819055610a31565b604051633db0d5b960e01b815260040160405180910390fd5b817fe986e40cc8c151830d4f61050f4fb2e4add8567caad2d5f5496f9158e91fe4c782604051610a6391815260200190565b60405180910390a250506000600d55565b6000818152600c6020526040812060038101546004909101548291829182916001600160a01b038116918391610abb91600160a01b9091046001600160601b031690611b5a565b955090506001600160a01b03821615801590610ad45750805b6000978852600c6020526040909720600281015460019091015497989597909650949350505050565b33600090815260208190526040902054600114610b2d5760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b03811660008181526020819052604080822060019055517fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a609190a250565b600b8181548110610b8257600080fd5b600091825260209091200154905081565b600d54600103610bb6576040516305fb981560e51b815260040160405180910390fd5b6001600d55600e546003908111610be057604051636afb25d560e11b815260040160405180910390fd5b6000878152600c60205260409020600301546001600160a01b031680610c195760405163cc16557d60e01b815260040160405180910390fd5b6000888152600c6020526040812060038101546004909101548291610c4f91600160a01b9091046001600160601b031690611b5a565b925090508015610c7257604051631c6ca9e360e01b815260040160405180910390fd5b5080871015610c94576040516327d10c5960e21b815260040160405180910390fd5b6000898152600c6020526040812060028101546001909101549091808b841115610cbe578b610cc0565b835b9050610ccc8582612051565b915082821115610cea57829150610ce3858361206e565b9050610d4c565b8282108015610cf857508381105b15610d4c5760095480610d0b8486612090565b1015610d4a57808411610d315760405163498489e760e01b815260040160405180910390fd5b610d3b8185612090565b9250610d47868461206e565b91505b505b610d568284612090565b9250610d628185612090565b604051633088df1760e11b81527f000000000000000000000000000000000000000000000000000000000000000060048201523060248201526001600160a01b038c81166044830152606482018490529195507f000000000000000000000000000000000000000000000000000000000000000090911690636111be2e90608401600060405180830381600087803b158015610dfd57600080fd5b505af1158015610e11573d6000803e3d6000fd5b50506001546001600160a01b03169150508815801590610e6357507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168b6001600160a01b031614155b8015610e815750806001600160a01b03168b6001600160a01b031614155b15610eed578a6001600160a01b0316638452c10e3385858e8e6040518663ffffffff1660e01b8152600401610eba9594939291906120a3565b600060405180830381600087803b158015610ed457600080fd5b505af1158015610ee8573d6000803e3d6000fd5b505050505b60025460405163bb35783b60e01b81523360048201526001600160a01b039182166024820152604481018590527f00000000000000000000000000000000000000000000000000000000000000009091169063bb35783b90606401600060405180830381600087803b158015610f6257600080fd5b505af1158015610f76573d6000803e3d6000fd5b50505050806001600160a01b031663c87193f47f000000000000000000000000000000000000000000000000000000000000000087600014610fb85785610fc2565b610fc286886120ef565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381600087803b15801561100057600080fd5b505af1158015611014573d6000803e3d6000fd5b505050505050826000036110305761102b8c611a86565b61110b565b816000036110ef57604051633088df1760e11b81527f000000000000000000000000000000000000000000000000000000000000000060048201523060248201526001600160a01b038681166044830152606482018590527f00000000000000000000000000000000000000000000000000000000000000001690636111be2e90608401600060405180830381600087803b1580156110ce57600080fd5b505af11580156110e2573d6000803e3d6000fd5b5050505061102b8c611a86565b60008c8152600c60205260409020600181018390556002018390555b604080518b81526020810186905290810182905260608101839052608081018490526001600160a01b038616908d907f05e309fd6ce72f2ab888a20056bb4210df08daed86f21f95053deb19964d86b19060a00160405180910390a350506000600d5550505050505050505050565b336000908152602081905260408120546001146111aa5760405163ea8e4eb560e01b815260040160405180910390fd5b600d546001036111cd576040516305fb981560e51b815260040160405180910390fd5b6001600d819055600e5481116111f657604051636afb25d560e11b815260040160405180910390fd5b8560000361121757604051633c76376d60e21b815260040160405180910390fd5b8460000361123857604051637632d31d60e11b815260040160405180910390fd5b6001600160a01b03841661125f5760405163617a951960e11b815260040160405180910390fd5b600a6000815461126e90612102565b91905081905591508160000361129757604051631a93c68960e11b815260040160405180910390fd5b600b80546001818101835560008390527f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db990910184905590546112da9190612090565b6000838152600c6020526040812091825560018201889055600282018790556001600160601b034216600160a01b026001600160a01b03871617600390920191909155611330611328611c21565b600554611dce565b905080600003611353576040516375d00c2f60e01b815260040160405180910390fd5b6000838152600c602052604090206004018190556008546001600160c01b03600160401b8204169067ffffffffffffffff16811515806113935750600081115b156114b0576000670de0b6b3a76400006113ad838c612051565b6113b7919061206e565b6113c190846120ef565b60025460405163f24e23eb60e01b81526001600160a01b0391821660048201528982166024820152604481018390529192507f0000000000000000000000000000000000000000000000000000000000000000169063f24e23eb90606401600060405180830381600087803b15801561143957600080fd5b505af115801561144d573d6000803e3d6000fd5b505060408051878152602081018e90529081018c9052606081018490526001600160a01b03808b1693508b16915088907f7c5bfdc0a5e8192f6cd4972f382cec69116862fb62e6abff8003874c58e064b89060800160405180910390a45061150b565b60408051848152602081018b9052908101899052600060608201526001600160a01b03808816919089169087907f7c5bfdc0a5e8192f6cd4972f382cec69116862fb62e6abff8003874c58e064b89060800160405180910390a45b50506000600d55509095945050505050565b3360009081526020819052604090205460011461154d5760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b038116600081815260208190526040808220829055517f184450df2e323acec0ed3b5c7531b81f9b4cdef7914dfd4c0a4317416bb5251b9190a250565b336000908152602081905260409020546001146115c15760405163ea8e4eb560e01b815260040160405180910390fd5b600d546001036115e4576040516305fb981560e51b815260040160405180910390fd5b6001600d556639b837ba3a32b960c91b82900361161b57600380546001600160a01b0319166001600160a01b03831617905561169f565b8162646f6760e81b0361164857600180546001600160a01b0319166001600160a01b03831617905561169f565b8162766f7760e81b0361167557600280546001600160a01b0319166001600160a01b03831617905561169f565b816363616c6360e01b03610a1857600480546001600160a01b0319166001600160a01b0383161790555b6040516001600160a01b038216815282907f41a50316b758972a692a69178de3d99c3138a652f5213364ee8eff829f22048a90602001610a63565b600d546001036116fd576040516305fb981560e51b815260040160405180910390fd5b6001600d55600e54600290811161172757604051636afb25d560e11b815260040160405180910390fd5b6000838152600c60205260409020600301546001600160a01b0316806117605760405163cc16557d60e01b815260040160405180910390fd5b6000848152600c60205260408120600381015460049091015461179391600160a01b90046001600160601b031690611b5a565b509050806117b457604051631e6a072d60e21b815260040160405180910390fd5b6000858152600c6020526040812060018101546002820154600390920180546001600160a01b0316600160a01b426001600160601b031602179055916117f8611c21565b9050600061180882600554611dce565b90508060000361182b576040516375d00c2f60e01b815260040160405180910390fd5b6000898152600c602052604090206004018190556008546001600160c01b03600160401b8204169067ffffffffffffffff168115158061186b5750600081115b15611a195760095480871080159061188c5750806118898688612051565b10155b156119b8576000670de0b6b3a76400006118a6848a612051565b6118b0919061206e565b6118ba90856120ef565b60025460405163f24e23eb60e01b81526001600160a01b0391821660048201528e82166024820152604481018390529192507f0000000000000000000000000000000000000000000000000000000000000000169063f24e23eb90606401600060405180830381600087803b15801561193257600080fd5b505af1158015611946573d6000803e3d6000fd5b505050508b6001600160a01b03168a6001600160a01b03168e7f275de7ecdd375b5e8049319f8b350686131c219dd4dc450a08e9cf83b03c865f888c8c876040516119aa949392919093845260208401929092526040830152606082015260800190565b60405180910390a450611a13565b6040805185815260208101899052908101879052600060608201526001600160a01b03808d1691908b16908e907f275de7ecdd375b5e8049319f8b350686131c219dd4dc450a08e9cf83b03c865f9060800160405180910390a45b50611a74565b6040805184815260208101889052908101869052600060608201526001600160a01b03808c1691908a16908d907f275de7ecdd375b5e8049319f8b350686131c219dd4dc450a08e9cf83b03c865f9060800160405180910390a45b50506000600d55505050505050505050565b600b805460009190611a9a90600190612090565b81548110611aaa57611aaa61211b565b90600052602060002001549050808214611b03576000828152600c6020526040902054600b805483919083908110611ae457611ae461211b565b6000918252602080832090910192909255838152600c90915260409020555b600b805480611b1457611b14612131565b600082815260208082208301600019908101839055909201909255928152600c909252506040812081815560018101829055600281018290556003810182905560040155565b60045460009081906001600160a01b031663487a239584611b846001600160601b03881642612090565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401602060405180830381865afa158015611bc5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611be99190612022565b600654909150611c026001600160601b03861642612090565b1180611c185750600754611c168285611df8565b105b91509250929050565b600354604051636cb1c69b60e11b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260009182916001600160a01b039091169063d9638d36906024016040805180830381865afa158015611c8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb19190612147565b509050600080826001600160a01b03166359e02dd76040518163ffffffff1660e01b81526004016040805180830381865afa158015611cf4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d189190612175565b9150915080611d395760405162bfc92160e01b815260040160405180910390fd5b611dc6611d4a633b9aca0084612051565b600360009054906101000a90046001600160a01b03166001600160a01b031663495d32cb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dc19190612022565b611df8565b935050505090565b60006b033b2e3c9fd0803ce8000000611de78385612051565b611df1919061206e565b9392505050565b600081611de76b033b2e3c9fd0803ce800000085612051565b602080825282518282018190526000918401906040840190835b81811015611e49578351835260209384019390920191600101611e2b565b509095945050505050565b600060208284031215611e6657600080fd5b5035919050565b60008060408385031215611e8057600080fd5b50508035926020909101359150565b6001600160a01b0381168114611ea457600080fd5b50565b600060208284031215611eb957600080fd5b8135611df181611e8f565b60008060008060008060a08789031215611edd57600080fd5b8635955060208701359450604087013593506060870135611efd81611e8f565b9250608087013567ffffffffffffffff811115611f1957600080fd5b8701601f81018913611f2a57600080fd5b803567ffffffffffffffff811115611f4157600080fd5b896020828401011115611f5357600080fd5b60208201935080925050509295509295509295565b60008060008060808587031215611f7e57600080fd5b84359350602085013592506040850135611f9781611e8f565b91506060850135611fa781611e8f565b939692955090935050565b60008060408385031215611fc557600080fd5b823591506020830135611fd781611e8f565b809150509250929050565b600080600080600060a08688031215611ffa57600080fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b60006020828403121561203457600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176120685761206861203b565b92915050565b60008261208b57634e487b7160e01b600052601260045260246000fd5b500490565b818103818111156120685761206861203b565b60018060a01b038616815284602082015283604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b808201808211156120685761206861203b565b6000600182016121145761211461203b565b5060010190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b6000806040838503121561215a57600080fd5b825161216581611e8f565b6020939093015192949293505050565b6000806040838503121561218857600080fd5b8251915060208301518015158114611fd757600080fdfea264697066735822122096d430768b7ebdb5ecabf0a9a9d8b1be76126e3d57b80b0c57810258d5e78a6064736f6c634300081c003300000000000000000000000016ca93f2f65d5495c874109fff38d11d39850b670000000000000000000000005113111a6b9dbeb84707c0d596cca11ae4ee81960000000000000000000000003fa88872368b9bfea50c35b35fff55c425c8ac530000000000000000000000002030803a2eab2a481f4ff358731c416eead94210000000000000000000000000efd766ccb38eaf1dfd701853bfce31359239f305425249444745442d444149000000000000000000000000000000000000000000000000000000000000000000e3d5de07962ca32a7c19385d38014e5bb57dfd870000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000038d7ea4c68000000000000000000000000006d79f82328ea3da61e066ebb2f88a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e8cd8a657b95bca51dd7bc35cd9d5dfbf9c05596000000000000000000000000aa89d1c41c12ebd230226907025472dbd687f1b8000000000000000000000000579d394e98bc8377038669e5a70961a24412a5e60000000000000000000000000000000000000000033b2e3c9fd0803ce80000000000000000000000000000000000000000000000000000000000000000005460000000000000000000000000000000000000000002e87669c308736a04000000000000000000000000000006d79f82328ea3da61e066ebb2f88a0000000000000000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000f59b2a5dcdf3f1e899b81756970508f1e8af2fb8

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106101735760003560e01c80637b103999116100de578063c11645bc11610097578063c5ce281e11610071578063c5ce281e146104b9578063d741e2f9146104e0578063def8f41b14610507578063fae036d51461052e57600080fd5b8063c11645bc14610444578063c1c0e9c41461046b578063c3b3ad7f1461049257600080fd5b80637b1039991461035a5780637bd2bea7146103815780637dc0d1d0146103a857806396f1b6be146103cf5780639e3ce1cf146103f6578063b56b83531461041d57600080fd5b806339b00e411161013057806339b00e411461028d57806349ed5931146102b4578063533e9bd1146102db578063568d4b6f146103025780636146195414610329578063626cb3c51461033357600080fd5b806301664f661461017857806304bda262146101bc57806313d8c840146101e357806315232515146102185780632e77468d1461023f57806336569e7714610266575b600080fd5b61019f7f0000000000000000000000006aafa71c9db937e4088dd2db72375038b744911c81565b6040516001600160a01b0390911681526020015b60405180910390f35b61019f7f000000000000000000000000cf883eac2a71679ffe9322e28cad474a660de7c681565b61020a7f000000000000000000000000000000000000000000000000000000000000546081565b6040519081526020016101b3565b61020a7f0000000000000000000000000000000000000000033b2e3c9fd0803ce800000081565b61019f7f0000000000000000000000005113111a6b9dbeb84707c0d596cca11ae4ee819681565b61019f7f00000000000000000000000016ca93f2f65d5495c874109fff38d11d39850b6781565b61019f7f000000000000000000000000a1dc966e8380f6d9a681d82e671a95d07a2124d981565b61020a7f000000000000000000000000000000000000000002e87669c308736a0400000081565b61019f7f000000000000000000000000000000000000000000000000000000000000000081565b61020a7f0000000000000000000000000000000000000000000000000011c37937e0800081565b610331610555565b005b61019f7f0000000000000000000000002030803a2eab2a481f4ff358731c416eead9421081565b61019f7f000000000000000000000000e8cd8a657b95bca51dd7bc35cd9d5dfbf9c0559681565b61019f7f000000000000000000000000efd766ccb38eaf1dfd701853bfce31359239f30581565b61019f7f000000000000000000000000e3d5de07962ca32a7c19385d38014e5bb57dfd8781565b61019f7f000000000000000000000000579d394e98bc8377038669e5a70961a24412a5e681565b61020a7f000000000000000000000006d79f82328ea3da61e066ebb2f88a00000000000081565b61020a7f000000000000000000000006d79f82328ea3da61e066ebb2f88a00000000000081565b61019f7f0000000000000000000000003fa88872368b9bfea50c35b35fff55c425c8ac5381565b61019f7f000000000000000000000000f59b2a5dcdf3f1e899b81756970508f1e8af2fb881565b61019f7f000000000000000000000000aa89d1c41c12ebd230226907025472dbd687f1b881565b61020a7f425249444745442d44414900000000000000000000000000000000000000000081565b61019f7f000000000000000000000000f90df17ce8a69451ce97f0b36a9b73ff60fd9d5481565b61020a7f0000000000000000000000000000000000000000000000000de0b6b3a764000081565b61020a7f00000000000000000000000000000000000000000000000000038d7ea4c6800081565b6040516332fd71af60e11b81526001600160a01b037f000000000000000000000000f90df17ce8a69451ce97f0b36a9b73ff60fd9d54811660048301527f0000000000000000000000005113111a6b9dbeb84707c0d596cca11ae4ee819616906365fae35e90602401600060405180830381600087803b1580156105d857600080fd5b505af11580156105ec573d6000803e3d6000fd5b505060405163ebecb39d60e01b81527f425249444745442d44414900000000000000000000000000000000000000000060048201526207069760ec1b60248201526001600160a01b037f000000000000000000000000f90df17ce8a69451ce97f0b36a9b73ff60fd9d54811660448301527f0000000000000000000000005113111a6b9dbeb84707c0d596cca11ae4ee819616925063ebecb39d9150606401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b5050604051630d05943f60e11b81527f425249444745442d4441490000000000000000000000000000000000000000006004820152621b585d60ea1b60248201526b033b2e3c9fd0803ce800000060448201527f0000000000000000000000005113111a6b9dbeb84707c0d596cca11ae4ee81966001600160a01b03169250631a0b287e9150606401600060405180830381600087803b15801561075c57600080fd5b505af1158015610770573d6000803e3d6000fd5b505050507f000000000000000000000000f90df17ce8a69451ce97f0b36a9b73ff60fd9d546001600160a01b031663181783586040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156107cf57600080fd5b505af11580156107e3573d6000803e3d6000fd5b5050604051631504460f60e01b81527f425249444745442d44414900000000000000000000000000000000000000000060048201527f0000000000000000000000005113111a6b9dbeb84707c0d596cca11ae4ee81966001600160a01b03169250631504460f9150602401600060405180830381600087803b15801561086857600080fd5b505af115801561087c573d6000803e3d6000fd5b50507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031691506109e5905057604051633b66319560e01b81527f425249444745442d44414900000000000000000000000000000000000000000060048201527f00000000000000000000000016ca93f2f65d5495c874109fff38d11d39850b676001600160a01b031690633b66319590602401600060405180830381600087803b15801561093157600080fd5b505af1158015610945573d6000803e3d6000fd5b50506040516332fd71af60e11b81526001600160a01b037f0000000000000000000000006aafa71c9db937e4088dd2db72375038b744911c811660048301527f00000000000000000000000016ca93f2f65d5495c874109fff38d11d39850b671692506365fae35e9150602401600060405180830381600087803b1580156109cc57600080fd5b505af11580156109e0573d6000803e3d6000fd5b505050505b604051630d05943f60e11b81527f425249444745442d4441490000000000000000000000000000000000000000006004820152636c696e6560e01b60248201527f000000000000000000000006d79f82328ea3da61e066ebb2f88a00000000000060448201527f00000000000000000000000016ca93f2f65d5495c874109fff38d11d39850b676001600160a01b031690631a0b287e90606401600060405180830381600087803b158015610a9957600080fd5b505af1158015610aad573d6000803e3d6000fd5b5050604051630d05943f60e11b81527f425249444745442d444149000000000000000000000000000000000000000000600482015263191d5cdd60e21b6024820152600060448201527f00000000000000000000000016ca93f2f65d5495c874109fff38d11d39850b676001600160a01b03169250631a0b287e9150606401600060405180830381600087803b158015610b4657600080fd5b505af1158015610b5a573d6000803e3d6000fd5b5050604051630a6ba04560e21b8152623a34b760e91b60048201527f0000000000000000000000000000000000000000000000000011c37937e0800060248201527f000000000000000000000000cf883eac2a71679ffe9322e28cad474a660de7c66001600160a01b031692506329ae81149150604401600060405180830381600087803b158015610beb57600080fd5b505af1158015610bff573d6000803e3d6000fd5b5050604051630a6ba04560e21b8152631d1bdd5d60e21b60048201527f00000000000000000000000000000000000000000000000000038d7ea4c6800060248201527f000000000000000000000000cf883eac2a71679ffe9322e28cad474a660de7c66001600160a01b031692506329ae81149150604401600060405180830381600087803b158015610c9157600080fd5b505af1158015610ca5573d6000803e3d6000fd5b50506040516328ec8bf160e21b81526001600160a01b037f000000000000000000000000a1dc966e8380f6d9a681d82e671a95d07a2124d9811660048301527f000000000000000000000000cf883eac2a71679ffe9322e28cad474a660de7c616925063a3b22fc49150602401600060405180830381600087803b158015610d2c57600080fd5b505af1158015610d40573d6000803e3d6000fd5b50506040516332fd71af60e11b81526001600160a01b037f000000000000000000000000a1dc966e8380f6d9a681d82e671a95d07a2124d9811660048301527f00000000000000000000000016ca93f2f65d5495c874109fff38d11d39850b671692506365fae35e9150602401600060405180830381600087803b158015610dc757600080fd5b505af1158015610ddb573d6000803e3d6000fd5b50506040516332fd71af60e11b81526001600160a01b037f000000000000000000000000a1dc966e8380f6d9a681d82e671a95d07a2124d9811660048301527f000000000000000000000000aa89d1c41c12ebd230226907025472dbd687f1b81692506365fae35e9150602401600060405180830381600087803b158015610e6257600080fd5b505af1158015610e76573d6000803e3d6000fd5b505060405163d4e8be8360e01b815262766f7760e81b60048201526001600160a01b037f0000000000000000000000002030803a2eab2a481f4ff358731c416eead94210811660248301527f000000000000000000000000a1dc966e8380f6d9a681d82e671a95d07a2124d916925063d4e8be839150604401600060405180830381600087803b158015610f0957600080fd5b505af1158015610f1d573d6000803e3d6000fd5b505060405163d4e8be8360e01b81526363616c6360e01b60048201526001600160a01b037f000000000000000000000000579d394e98bc8377038669e5a70961a24412a5e6811660248301527f000000000000000000000000a1dc966e8380f6d9a681d82e671a95d07a2124d916925063d4e8be839150604401600060405180830381600087803b158015610fb157600080fd5b505af1158015610fc5573d6000803e3d6000fd5b5050604051630a6ba04560e21b815262313ab360e91b60048201527f0000000000000000000000000000000000000000033b2e3c9fd0803ce800000060248201527f000000000000000000000000a1dc966e8380f6d9a681d82e671a95d07a2124d96001600160a01b031692506329ae81149150604401600060405180830381600087803b15801561105657600080fd5b505af115801561106a573d6000803e3d6000fd5b5050604051630a6ba04560e21b8152631d185a5b60e21b60048201527f000000000000000000000000000000000000000000000000000000000000546060248201527f000000000000000000000000a1dc966e8380f6d9a681d82e671a95d07a2124d96001600160a01b031692506329ae81149150604401600060405180830381600087803b1580156110fc57600080fd5b505af1158015611110573d6000803e3d6000fd5b5050604051630a6ba04560e21b8152630637573760e41b60048201527f000000000000000000000000000000000000000002e87669c308736a0400000060248201527f000000000000000000000000a1dc966e8380f6d9a681d82e671a95d07a2124d96001600160a01b031692506329ae81149150604401600060405180830381600087803b1580156111a257600080fd5b505af11580156111b6573d6000803e3d6000fd5b5050604051630a6ba04560e21b81526207469760ec1b6004820152600060248201527f000000000000000000000000a1dc966e8380f6d9a681d82e671a95d07a2124d96001600160a01b031692506329ae81149150604401600060405180830381600087803b15801561122857600080fd5b505af115801561123c573d6000803e3d6000fd5b5050604051630a6ba04560e21b8152630636869760e41b6004820152600060248201527f000000000000000000000000a1dc966e8380f6d9a681d82e671a95d07a2124d96001600160a01b031692506329ae81149150604401600060405180830381600087803b1580156112af57600080fd5b505af11580156112c3573d6000803e3d6000fd5b505060405163ebecb39d60e01b81527f425249444745442d4441490000000000000000000000000000000000000000006004820152630636c69760e41b60248201526001600160a01b037f000000000000000000000000a1dc966e8380f6d9a681d82e671a95d07a2124d9811660448301527f000000000000000000000000aa89d1c41c12ebd230226907025472dbd687f1b816925063ebecb39d9150606401600060405180830381600087803b15801561137d57600080fd5b505af1158015611391573d6000803e3d6000fd5b5050604051630d05943f60e11b81527f425249444745442d444149000000000000000000000000000000000000000000600482015263063686f760e41b60248201527f0000000000000000000000000000000000000000000000000de0b6b3a764000060448201527f000000000000000000000000aa89d1c41c12ebd230226907025472dbd687f1b86001600160a01b03169250631a0b287e9150606401600060405180830381600087803b15801561144957600080fd5b505af115801561145d573d6000803e3d6000fd5b5050604051630d05943f60e11b81527f425249444745442d444149000000000000000000000000000000000000000000600482015263686f6c6560e01b60248201527f000000000000000000000006d79f82328ea3da61e066ebb2f88a00000000000060448201527f000000000000000000000000aa89d1c41c12ebd230226907025472dbd687f1b86001600160a01b03169250631a0b287e9150606401600060405180830381600087803b15801561151557600080fd5b505af1158015611529573d6000803e3d6000fd5b505050507f000000000000000000000000a1dc966e8380f6d9a681d82e671a95d07a2124d96001600160a01b0316630cbb58626040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561158857600080fd5b505af115801561159c573d6000803e3d6000fd5b5050507f000000000000000000000000e8cd8a657b95bca51dd7bc35cd9d5dfbf9c055966001600160a01b031615905061173957604051631c79c0e560e11b81527f425249444745442d44414900000000000000000000000000000000000000000060048201526001600160a01b037f000000000000000000000000efd766ccb38eaf1dfd701853bfce31359239f305811660248301527f0000000000000000000000006aafa71c9db937e4088dd2db72375038b744911c811660448301527f000000000000000000000000f90df17ce8a69451ce97f0b36a9b73ff60fd9d54811660648301527f000000000000000000000000a1dc966e8380f6d9a681d82e671a95d07a2124d981166084830152600060a48301527f000000000000000000000000cf883eac2a71679ffe9322e28cad474a660de7c6811660c48301527f000000000000000000000000e8cd8a657b95bca51dd7bc35cd9d5dfbf9c0559616906338f381ca9060e401600060405180830381600087803b15801561172057600080fd5b505af1158015611734573d6000803e3d6000fd5b505050505b7f000000000000000000000000a1dc966e8380f6d9a681d82e671a95d07a2124d96001600160a01b03167f000000000000000000000000cf883eac2a71679ffe9322e28cad474a660de7c66001600160a01b03167f425249444745442d4441490000000000000000000000000000000000000000007f2ed482f800439d546a30151101b134d6ca228c9f42e16973982b4e8dd20043ef7f000000000000000000000006d79f82328ea3da61e066ebb2f88a0000000000007f0000000000000000000000000000000000000000000000000011c37937e080007f00000000000000000000000000000000000000000000000000038d7ea4c68000604051611852939291909283526020830191909152604082015260600190565b60405180910390a456fea2646970667358221220ebe98196d45d11812e12314096223cab8700527c761efc7346cb77059f1c409c64736f6c634300081c0033