diff --git a/hardhat.config.ts b/hardhat.config.ts index 8926a13..c6fad48 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -50,11 +50,11 @@ const safes = { }, ethereum: { address: "0x30Fa557608017afB6E8e4ABe8027787C00473FF0", - url: "https://safe-transaction.ethereum.safe.global", + url: "https://safe-transaction-mainnet.safe.global", }, base: { address: "0x2E816EA2A7Db3DB4C74298cae0d455f0F800E92A", - url: "https://safe-transaction.base.safe.global", + url: "https://safe-transaction-base.safe.global", }, hardhat: { address: "0x0", diff --git a/hardhat/deploy/01-LDY.ts b/hardhat/deploy/01-LDY.ts index 1d28e9d..4f40e1e 100644 --- a/hardhat/deploy/01-LDY.ts +++ b/hardhat/deploy/01-LDY.ts @@ -4,12 +4,12 @@ import { parseUnits } from "viem"; module.exports = (async ({ getNamedAccounts, deployments }) => { const { deployer } = await getNamedAccounts(); - await deployments.deploy("TSTTOKEN", { + await deployments.deploy("LDY", { from: deployer, - contract: "TSTTOKEN", + contract: "LDY", log: true, waitConfirmations: 2, - args: ["Test Token", "TSTTOKEN", 18, parseUnits(String(75_000_000), 18)], + args: ["Ledgity Token", "LDY", 18, parseUnits(String(75_000_000), 18)], deterministicDeployment: false, }); }) as DeployFunction; \ No newline at end of file diff --git a/hardhat/deployments/arbitrum/TSTTOKEN.json b/hardhat/deployments/arbitrum/LDY.json similarity index 61% rename from hardhat/deployments/arbitrum/TSTTOKEN.json rename to hardhat/deployments/arbitrum/LDY.json index 32ebf76..232d32d 100644 --- a/hardhat/deployments/arbitrum/TSTTOKEN.json +++ b/hardhat/deployments/arbitrum/LDY.json @@ -1,5 +1,5 @@ { - "address": "0xE108E03c34de9586535018d7a205C050C16c2424", + "address": "0x999FAF0AF2fF109938eeFE6A7BF91CA56f0D07e1", "abi": [ { "inputs": [ @@ -784,70 +784,70 @@ "type": "function" } ], - "transactionHash": "0x3cd289a8dd4e0cef303cb0ad31c2eaeba085a5bb8e66e017674760aec885fc88", + "transactionHash": "0xfa0c86c8cc4d2bb8b1e0658c3ac3bd5e00d5e0401261d72f539f0d043de352c1", "receipt": { "to": "0x972c17D0adA071db4a0395505dD3Ad0a80809053", - "from": "0x1c2285D8f83EabaD37Fb9202E0093ea201589934", - "contractAddress": "0xE108E03c34de9586535018d7a205C050C16c2424", - "transactionIndex": 2, - "gasUsed": "2208896", + "from": "0x65b1B95F7b886c87Eb04E70bfE73D00fc640b046", + "contractAddress": "0x999FAF0AF2fF109938eeFE6A7BF91CA56f0D07e1", + "transactionIndex": 1, + "gasUsed": "2557364", "logsBloom": "0x00000000400000000000000000000000000000000000000000000000040000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000040000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000440000000000000000004000000000000000000000000000000000000000000000000000080000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x99d7d64cbc98c4f9a01278f61a2144c553806a76d86549fa073a3a819f48b162", - "transactionHash": "0x3cd289a8dd4e0cef303cb0ad31c2eaeba085a5bb8e66e017674760aec885fc88", + "blockHash": "0xaf88a614a71840f6b93ae5bc01f5c3c61e479a3e7cf0470dc21a2716b5eb2bb7", + "transactionHash": "0xfa0c86c8cc4d2bb8b1e0658c3ac3bd5e00d5e0401261d72f539f0d043de352c1", "logs": [ { - "transactionIndex": 2, - "blockNumber": 207764020, - "transactionHash": "0x3cd289a8dd4e0cef303cb0ad31c2eaeba085a5bb8e66e017674760aec885fc88", + "transactionIndex": 1, + "blockNumber": 208821798, + "transactionHash": "0xfa0c86c8cc4d2bb8b1e0658c3ac3bd5e00d5e0401261d72f539f0d043de352c1", "address": "0x972c17D0adA071db4a0395505dD3Ad0a80809053", "topics": [ "0x66753cd2356569ee081232e3be8909b950e0a76c1f8460c3a5e3c2be32b11bed" ], - "data": "0x0000000000000000000000007cbb62eaa69f79e6873cd1ecb2392971036cfaa4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f4000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001da44c8c9ea1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000001d2a60c06040523480156200001157600080fd5b5060405162001c2a38038062001c2a833981016040819052620000349162000277565b338060008686818160036200004a838262000391565b50600462000059828262000391565b5050506001600160a01b0384169150620000bc90505760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600580546001600160a01b0319166001600160a01b0384811691909117909155811615620000ef57620000ef8162000106565b50505060ff90911660805260a052506200045d9050565b336001600160a01b03821603620001605760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000b3565b600680546001600160a01b0319166001600160a01b03838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001da57600080fd5b81516001600160401b0380821115620001f757620001f7620001b2565b604051601f8301601f19908116603f01168101908282118183101715620002225762000222620001b2565b816040528381526020925086838588010111156200023f57600080fd5b600091505b8382101562000263578582018301518183018401529082019062000244565b600093810190920192909252949350505050565b600080600080608085870312156200028e57600080fd5b84516001600160401b0380821115620002a657600080fd5b620002b488838901620001c8565b95506020870151915080821115620002cb57600080fd5b50620002da87828801620001c8565b935050604085015160ff81168114620002f257600080fd5b6060959095015193969295505050565b600181811c908216806200031757607f821691505b6020821081036200033857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200038c57600081815260208120601f850160051c81016020861015620003675750805b601f850160051c820191505b81811015620003885782815560010162000373565b5050505b505050565b81516001600160401b03811115620003ad57620003ad620001b2565b620003c581620003be845462000302565b846200033e565b602080601f831160018114620003fd5760008415620003e45750858301515b600019600386901b1c1916600185901b17855562000388565b600085815260208120601f198616915b828110156200042e578886015182559484019460019091019084016200040d565b50858210156200044d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a051611799620004916000396000818161042d01528181610715015261073f0152600061027101526117996000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c806379cc67901161010f578063c2e3273d116100a2578063d73dd62311610071578063d73dd62314610451578063dd62ed3e14610464578063f2fde38b14610477578063f81094f31461048a57600080fd5b8063c2e3273d146103f2578063c630948d14610405578063c64d0ebc14610418578063d5abeb011461042b57600080fd5b80639dc29fac116100de5780639dc29fac146103a6578063a457c2d7146103b9578063a9059cbb146103cc578063aa271e1a146103df57600080fd5b806379cc67901461036857806386fe8b431461037b5780638da5cb5b1461038357806395d89b411461039e57600080fd5b806340c10f19116101875780636618846311610156578063661884631461030f5780636b32810b1461032257806370a082311461033757806379ba50971461036057600080fd5b806340c10f19146102c157806342966c68146102d65780634334614a146102e95780634f5632f8146102fc57600080fd5b806323b872dd116101c357806323b872dd14610257578063313ce5671461026a578063395093511461029b5780634000aea0146102ae57600080fd5b806301ffc9a7146101f557806306fdde031461021d578063095ea7b31461023257806318160ddd14610245575b600080fd5b6102086102033660046113d6565b61049d565b60405190151581526020015b60405180910390f35b61022561050a565b6040516102149190611446565b610208610240366004611475565b61059c565b6002545b604051908152602001610214565b61020861026536600461149f565b6105b4565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610214565b6102086102a9366004611475565b6105d8565b6102086102bc3660046114f1565b6105fa565b6102d46102cf366004611475565b6106d0565b005b6102d46102e43660046115bc565b6107b8565b6102086102f73660046115d5565b6107ec565b6102d461030a3660046115d5565b6107f9565b61020861031d366004611475565b610848565b61032a61085b565b60405161021491906115f0565b6102496103453660046115d5565b6001600160a01b031660009081526020819052604090205490565b6102d461086c565b6102d4610376366004611475565b61091a565b61032a610950565b6005546040516001600160a01b039091168152602001610214565b61022561095c565b6102d46103b4366004611475565b61096b565b6102086103c7366004611475565b610975565b6102086103da366004611475565b6109f0565b6102086103ed3660046115d5565b6109fe565b6102d46104003660046115d5565b610a0b565b6102d46104133660046115d5565b610a5a565b6102d46104263660046115d5565b610a68565b7f0000000000000000000000000000000000000000000000000000000000000000610249565b6102d461045f366004611475565b610ab7565b61024961047236600461163d565b610ac1565b6102d46104853660046115d5565b610aec565b6102d46104983660046115d5565b610afd565b60006001600160e01b031982166336372b0760e01b14806104ce57506001600160e01b03198216630200057560e51b145b806104e957506001600160e01b0319821663e6599b4d60e01b145b8061050457506001600160e01b031982166301ffc9a760e01b145b92915050565b60606003805461051990611670565b80601f016020809104026020016040519081016040528092919081815260200182805461054590611670565b80156105925780601f1061056757610100808354040283529160200191610592565b820191906000526020600020905b81548152906001019060200180831161057557829003601f168201915b5050505050905090565b6000336105aa818585610b4c565b5060019392505050565b6000336105c2858285610b73565b6105cd858585610be7565b506001949350505050565b6000336105aa8185856105eb8383610ac1565b6105f591906116c0565b610b4c565b600061060684846109f0565b50836001600160a01b0316336001600160a01b03167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16858560405161064c9291906116d3565b60405180910390a36001600160a01b0384163b156105aa57604051635260769b60e11b81526001600160a01b0385169063a4c0ed3690610694903390879087906004016116f4565b600060405180830381600087803b1580156106ae57600080fd5b505af11580156106c2573d6000803e3d6000fd5b505050505060019392505050565b6106d9336109fe565b6106fd5760405163e2c8c9d560e01b81523360048201526024015b60405180910390fd5b81306001600160a01b0382160361071357600080fd5b7f00000000000000000000000000000000000000000000000000000000000000001580159061077457507f00000000000000000000000000000000000000000000000000000000000000008261076860025490565b61077291906116c0565b115b156107a9578161078360025490565b61078d91906116c0565b60405163cbbf111360e01b81526004016106f491815260200190565b6107b38383610c08565b505050565b6107c1336107ec565b6107e05760405163c820b10b60e01b81523360048201526024016106f4565b6107e981610cc7565b50565b6000610504600983610cd1565b610801610cf3565b61080c600982610d48565b156107e9576040516001600160a01b038216907f0a675452746933cefe3d74182e78db7afe57ba60eaa4234b5d85e9aa41b0610c90600090a250565b60006108548383610975565b9392505050565b60606108676007610d5d565b905090565b6006546001600160a01b031633146108bf5760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b60448201526064016106f4565b600580546001600160a01b0319808216339081179093556006805490911690556040516001600160a01b03909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b610923336107ec565b6109425760405163c820b10b60e01b81523360048201526024016106f4565b61094c8282610d6a565b5050565b60606108676009610d5d565b60606004805461051990611670565b61094c828261091a565b600033816109838286610ac1565b9050838110156109e35760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016106f4565b6105cd8286868403610b4c565b6000336105aa818585610be7565b6000610504600783610cd1565b610a13610cf3565b610a1e600782610d7f565b156107e9576040516001600160a01b038216907fe46fef8bbff1389d9010703cf8ebb363fb3daf5bf56edc27080b67bc8d9251ea90600090a250565b610a6381610a0b565b6107e9815b610a70610cf3565b610a7b600982610d7f565b156107e9576040516001600160a01b038216907f92308bb7573b2a3d17ddb868b39d8ebec433f3194421abc22d084f89658c9bad90600090a250565b6107b382826105d8565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610af4610cf3565b6107e981610d94565b610b05610cf3565b610b10600782610d48565b156107e9576040516001600160a01b038216907fed998b960f6340d045f620c119730f7aa7995e7425c2401d3a5b64ff998a59e990600090a250565b81306001600160a01b03821603610b6257600080fd5b610b6d848484610e3e565b50505050565b6000610b7f8484610ac1565b90506000198114610b6d5781811015610bda5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106f4565b610b6d8484848403610b4c565b81306001600160a01b03821603610bfd57600080fd5b610b6d848484610f62565b6001600160a01b038216610c5e5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106f4565b8060026000828254610c7091906116c0565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6107e93382611106565b6001600160a01b03811660009081526001830160205260408120541515610854565b6005546001600160a01b03163314610d465760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b60448201526064016106f4565b565b6000610854836001600160a01b038416611238565b606060006108548361132b565b610d75823383610b73565b61094c8282611106565b6000610854836001600160a01b038416611387565b336001600160a01b03821603610dec5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106f4565b600680546001600160a01b0319166001600160a01b03838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b6001600160a01b038316610ea05760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016106f4565b6001600160a01b038216610f015760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016106f4565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b038316610fc65760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016106f4565b6001600160a01b0382166110285760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016106f4565b6001600160a01b038316600090815260208190526040902054818110156110a05760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016106f4565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610b6d565b6001600160a01b0382166111665760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016106f4565b6001600160a01b038216600090815260208190526040902054818110156111da5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016106f4565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6000818152600183016020526040812054801561132157600061125c600183611724565b855490915060009061127090600190611724565b90508181146112d557600086600001828154811061129057611290611737565b90600052602060002001549050808760000184815481106112b3576112b3611737565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806112e6576112e661174d565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610504565b6000915050610504565b60608160000180548060200260200160405190810160405280929190818152602001828054801561137b57602002820191906000526020600020905b815481526020019060010190808311611367575b50505050509050919050565b60008181526001830160205260408120546113ce57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610504565b506000610504565b6000602082840312156113e857600080fd5b81356001600160e01b03198116811461085457600080fd5b6000815180845260005b818110156114265760208185018101518683018201520161140a565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006108546020830184611400565b80356001600160a01b038116811461147057600080fd5b919050565b6000806040838503121561148857600080fd5b61149183611459565b946020939093013593505050565b6000806000606084860312156114b457600080fd5b6114bd84611459565b92506114cb60208501611459565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b60008060006060848603121561150657600080fd5b61150f84611459565b925060208401359150604084013567ffffffffffffffff8082111561153357600080fd5b818601915086601f83011261154757600080fd5b813581811115611559576115596114db565b604051601f8201601f19908116603f01168101908382118183101715611581576115816114db565b8160405282815289602084870101111561159a57600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b6000602082840312156115ce57600080fd5b5035919050565b6000602082840312156115e757600080fd5b61085482611459565b6020808252825182820181905260009190848201906040850190845b818110156116315783516001600160a01b03168352928401929184019160010161160c565b50909695505050505050565b6000806040838503121561165057600080fd5b61165983611459565b915061166760208401611459565b90509250929050565b600181811c9082168061168457607f821691505b6020821081036116a457634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610504576105046116aa565b8281526040602082015260006116ec6040830184611400565b949350505050565b60018060a01b038416815282602082015260606040820152600061171b6060830184611400565b95945050505050565b81810381811115610504576105046116aa565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fdfea26469706673582212205a3a81505b3271adf6e889a8843a188eefdd55c30388fd44e65ed00d036803df64736f6c63430008140033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000003e09de2596099e2b000000000000000000000000000000000000000000000000000000000000000000000a5465737420546f6b656e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008545354544f4b454e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000820000000000000000000000001c2285d8f83eabad37fb9202e0093ea201589934000000000000000000000000000000000000000000000000000000000000000001d45d1acbb908c7bdbeb9f0dc1f8d32b62b3f640ac97ace37707969d7c8a11a055502895f9452224e5fc24cdf774307f16f89ab1f453a9c03283232accc6013ab1f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000001c2285d8f83eabad37fb9202e0093ea2015899340000000000000000000000000000000000000000000000000000000000000002", - "logIndex": 6, - "blockHash": "0x99d7d64cbc98c4f9a01278f61a2144c553806a76d86549fa073a3a819f48b162" + "data": "0x0000000000000000000000007cbb62eaa69f79e6873cd1ecb2392971036cfaa4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f4000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001da44c8c9ea1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000001d2a60c06040523480156200001157600080fd5b5060405162001c2a38038062001c2a833981016040819052620000349162000277565b338060008686818160036200004a838262000391565b50600462000059828262000391565b5050506001600160a01b0384169150620000bc90505760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600580546001600160a01b0319166001600160a01b0384811691909117909155811615620000ef57620000ef8162000106565b50505060ff90911660805260a052506200045d9050565b336001600160a01b03821603620001605760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000b3565b600680546001600160a01b0319166001600160a01b03838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001da57600080fd5b81516001600160401b0380821115620001f757620001f7620001b2565b604051601f8301601f19908116603f01168101908282118183101715620002225762000222620001b2565b816040528381526020925086838588010111156200023f57600080fd5b600091505b8382101562000263578582018301518183018401529082019062000244565b600093810190920192909252949350505050565b600080600080608085870312156200028e57600080fd5b84516001600160401b0380821115620002a657600080fd5b620002b488838901620001c8565b95506020870151915080821115620002cb57600080fd5b50620002da87828801620001c8565b935050604085015160ff81168114620002f257600080fd5b6060959095015193969295505050565b600181811c908216806200031757607f821691505b6020821081036200033857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200038c57600081815260208120601f850160051c81016020861015620003675750805b601f850160051c820191505b81811015620003885782815560010162000373565b5050505b505050565b81516001600160401b03811115620003ad57620003ad620001b2565b620003c581620003be845462000302565b846200033e565b602080601f831160018114620003fd5760008415620003e45750858301515b600019600386901b1c1916600185901b17855562000388565b600085815260208120601f198616915b828110156200042e578886015182559484019460019091019084016200040d565b50858210156200044d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a051611799620004916000396000818161042d01528181610715015261073f0152600061027101526117996000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c806379cc67901161010f578063c2e3273d116100a2578063d73dd62311610071578063d73dd62314610451578063dd62ed3e14610464578063f2fde38b14610477578063f81094f31461048a57600080fd5b8063c2e3273d146103f2578063c630948d14610405578063c64d0ebc14610418578063d5abeb011461042b57600080fd5b80639dc29fac116100de5780639dc29fac146103a6578063a457c2d7146103b9578063a9059cbb146103cc578063aa271e1a146103df57600080fd5b806379cc67901461036857806386fe8b431461037b5780638da5cb5b1461038357806395d89b411461039e57600080fd5b806340c10f19116101875780636618846311610156578063661884631461030f5780636b32810b1461032257806370a082311461033757806379ba50971461036057600080fd5b806340c10f19146102c157806342966c68146102d65780634334614a146102e95780634f5632f8146102fc57600080fd5b806323b872dd116101c357806323b872dd14610257578063313ce5671461026a578063395093511461029b5780634000aea0146102ae57600080fd5b806301ffc9a7146101f557806306fdde031461021d578063095ea7b31461023257806318160ddd14610245575b600080fd5b6102086102033660046113d6565b61049d565b60405190151581526020015b60405180910390f35b61022561050a565b6040516102149190611446565b610208610240366004611475565b61059c565b6002545b604051908152602001610214565b61020861026536600461149f565b6105b4565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610214565b6102086102a9366004611475565b6105d8565b6102086102bc3660046114f1565b6105fa565b6102d46102cf366004611475565b6106d0565b005b6102d46102e43660046115bc565b6107b8565b6102086102f73660046115d5565b6107ec565b6102d461030a3660046115d5565b6107f9565b61020861031d366004611475565b610848565b61032a61085b565b60405161021491906115f0565b6102496103453660046115d5565b6001600160a01b031660009081526020819052604090205490565b6102d461086c565b6102d4610376366004611475565b61091a565b61032a610950565b6005546040516001600160a01b039091168152602001610214565b61022561095c565b6102d46103b4366004611475565b61096b565b6102086103c7366004611475565b610975565b6102086103da366004611475565b6109f0565b6102086103ed3660046115d5565b6109fe565b6102d46104003660046115d5565b610a0b565b6102d46104133660046115d5565b610a5a565b6102d46104263660046115d5565b610a68565b7f0000000000000000000000000000000000000000000000000000000000000000610249565b6102d461045f366004611475565b610ab7565b61024961047236600461163d565b610ac1565b6102d46104853660046115d5565b610aec565b6102d46104983660046115d5565b610afd565b60006001600160e01b031982166336372b0760e01b14806104ce57506001600160e01b03198216630200057560e51b145b806104e957506001600160e01b0319821663e6599b4d60e01b145b8061050457506001600160e01b031982166301ffc9a760e01b145b92915050565b60606003805461051990611670565b80601f016020809104026020016040519081016040528092919081815260200182805461054590611670565b80156105925780601f1061056757610100808354040283529160200191610592565b820191906000526020600020905b81548152906001019060200180831161057557829003601f168201915b5050505050905090565b6000336105aa818585610b4c565b5060019392505050565b6000336105c2858285610b73565b6105cd858585610be7565b506001949350505050565b6000336105aa8185856105eb8383610ac1565b6105f591906116c0565b610b4c565b600061060684846109f0565b50836001600160a01b0316336001600160a01b03167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16858560405161064c9291906116d3565b60405180910390a36001600160a01b0384163b156105aa57604051635260769b60e11b81526001600160a01b0385169063a4c0ed3690610694903390879087906004016116f4565b600060405180830381600087803b1580156106ae57600080fd5b505af11580156106c2573d6000803e3d6000fd5b505050505060019392505050565b6106d9336109fe565b6106fd5760405163e2c8c9d560e01b81523360048201526024015b60405180910390fd5b81306001600160a01b0382160361071357600080fd5b7f00000000000000000000000000000000000000000000000000000000000000001580159061077457507f00000000000000000000000000000000000000000000000000000000000000008261076860025490565b61077291906116c0565b115b156107a9578161078360025490565b61078d91906116c0565b60405163cbbf111360e01b81526004016106f491815260200190565b6107b38383610c08565b505050565b6107c1336107ec565b6107e05760405163c820b10b60e01b81523360048201526024016106f4565b6107e981610cc7565b50565b6000610504600983610cd1565b610801610cf3565b61080c600982610d48565b156107e9576040516001600160a01b038216907f0a675452746933cefe3d74182e78db7afe57ba60eaa4234b5d85e9aa41b0610c90600090a250565b60006108548383610975565b9392505050565b60606108676007610d5d565b905090565b6006546001600160a01b031633146108bf5760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b60448201526064016106f4565b600580546001600160a01b0319808216339081179093556006805490911690556040516001600160a01b03909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b610923336107ec565b6109425760405163c820b10b60e01b81523360048201526024016106f4565b61094c8282610d6a565b5050565b60606108676009610d5d565b60606004805461051990611670565b61094c828261091a565b600033816109838286610ac1565b9050838110156109e35760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016106f4565b6105cd8286868403610b4c565b6000336105aa818585610be7565b6000610504600783610cd1565b610a13610cf3565b610a1e600782610d7f565b156107e9576040516001600160a01b038216907fe46fef8bbff1389d9010703cf8ebb363fb3daf5bf56edc27080b67bc8d9251ea90600090a250565b610a6381610a0b565b6107e9815b610a70610cf3565b610a7b600982610d7f565b156107e9576040516001600160a01b038216907f92308bb7573b2a3d17ddb868b39d8ebec433f3194421abc22d084f89658c9bad90600090a250565b6107b382826105d8565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610af4610cf3565b6107e981610d94565b610b05610cf3565b610b10600782610d48565b156107e9576040516001600160a01b038216907fed998b960f6340d045f620c119730f7aa7995e7425c2401d3a5b64ff998a59e990600090a250565b81306001600160a01b03821603610b6257600080fd5b610b6d848484610e3e565b50505050565b6000610b7f8484610ac1565b90506000198114610b6d5781811015610bda5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106f4565b610b6d8484848403610b4c565b81306001600160a01b03821603610bfd57600080fd5b610b6d848484610f62565b6001600160a01b038216610c5e5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106f4565b8060026000828254610c7091906116c0565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6107e93382611106565b6001600160a01b03811660009081526001830160205260408120541515610854565b6005546001600160a01b03163314610d465760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b60448201526064016106f4565b565b6000610854836001600160a01b038416611238565b606060006108548361132b565b610d75823383610b73565b61094c8282611106565b6000610854836001600160a01b038416611387565b336001600160a01b03821603610dec5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106f4565b600680546001600160a01b0319166001600160a01b03838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b6001600160a01b038316610ea05760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016106f4565b6001600160a01b038216610f015760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016106f4565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b038316610fc65760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016106f4565b6001600160a01b0382166110285760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016106f4565b6001600160a01b038316600090815260208190526040902054818110156110a05760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016106f4565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610b6d565b6001600160a01b0382166111665760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016106f4565b6001600160a01b038216600090815260208190526040902054818110156111da5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016106f4565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6000818152600183016020526040812054801561132157600061125c600183611724565b855490915060009061127090600190611724565b90508181146112d557600086600001828154811061129057611290611737565b90600052602060002001549050808760000184815481106112b3576112b3611737565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806112e6576112e661174d565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610504565b6000915050610504565b60608160000180548060200260200160405190810160405280929190818152602001828054801561137b57602002820191906000526020600020905b815481526020019060010190808311611367575b50505050509050919050565b60008181526001830160205260408120546113ce57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610504565b506000610504565b6000602082840312156113e857600080fd5b81356001600160e01b03198116811461085457600080fd5b6000815180845260005b818110156114265760208185018101518683018201520161140a565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006108546020830184611400565b80356001600160a01b038116811461147057600080fd5b919050565b6000806040838503121561148857600080fd5b61149183611459565b946020939093013593505050565b6000806000606084860312156114b457600080fd5b6114bd84611459565b92506114cb60208501611459565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b60008060006060848603121561150657600080fd5b61150f84611459565b925060208401359150604084013567ffffffffffffffff8082111561153357600080fd5b818601915086601f83011261154757600080fd5b813581811115611559576115596114db565b604051601f8201601f19908116603f01168101908382118183101715611581576115816114db565b8160405282815289602084870101111561159a57600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b6000602082840312156115ce57600080fd5b5035919050565b6000602082840312156115e757600080fd5b61085482611459565b6020808252825182820181905260009190848201906040850190845b818110156116315783516001600160a01b03168352928401929184019160010161160c565b50909695505050505050565b6000806040838503121561165057600080fd5b61165983611459565b915061166760208401611459565b90509250929050565b600181811c9082168061168457607f821691505b6020821081036116a457634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610504576105046116aa565b8281526040602082015260006116ec6040830184611400565b949350505050565b60018060a01b038416815282602082015260606040820152600061171b6060830184611400565b95945050505050565b81810381811115610504576105046116aa565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fdfea264697066735822122026bf827ff7c4546d08bc173f7cb82c7ccf3be629370907c1d7e2e74f372b4c0164736f6c63430008140033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000003e09de2596099e2b000000000000000000000000000000000000000000000000000000000000000000000d4c65646769747920546f6b656e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034c445900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008200000000000000000000000065b1b95f7b886c87eb04e70bfe73d00fc640b046000000000000000000000000000000000000000000000000000000000000000001cec9c8ddbd90ad2b18b0c9c8cdafc22305f2e04149a9262a545589023e21f64477373c8bb8f5e5bf0be73c4192d7a370a5073779028232ba043db2c5a1af00b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000065b1b95f7b886c87eb04e70bfe73d00fc640b0460000000000000000000000000000000000000000000000000000000000000002", + "logIndex": 0, + "blockHash": "0xaf88a614a71840f6b93ae5bc01f5c3c61e479a3e7cf0470dc21a2716b5eb2bb7" }, { - "transactionIndex": 2, - "blockNumber": 207764020, - "transactionHash": "0x3cd289a8dd4e0cef303cb0ad31c2eaeba085a5bb8e66e017674760aec885fc88", + "transactionIndex": 1, + "blockNumber": 208821798, + "transactionHash": "0xfa0c86c8cc4d2bb8b1e0658c3ac3bd5e00d5e0401261d72f539f0d043de352c1", "address": "0x972c17D0adA071db4a0395505dD3Ad0a80809053", "topics": [ "0x4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b511" ], - "data": "0x000000000000000000000000e108e03c34de9586535018d7a205c050c16c2424", - "logIndex": 7, - "blockHash": "0x99d7d64cbc98c4f9a01278f61a2144c553806a76d86549fa073a3a819f48b162" + "data": "0x000000000000000000000000999faf0af2ff109938eefe6a7bf91ca56f0d07e1", + "logIndex": 1, + "blockHash": "0xaf88a614a71840f6b93ae5bc01f5c3c61e479a3e7cf0470dc21a2716b5eb2bb7" }, { - "transactionIndex": 2, - "blockNumber": 207764020, - "transactionHash": "0x3cd289a8dd4e0cef303cb0ad31c2eaeba085a5bb8e66e017674760aec885fc88", + "transactionIndex": 1, + "blockNumber": 208821798, + "transactionHash": "0xfa0c86c8cc4d2bb8b1e0658c3ac3bd5e00d5e0401261d72f539f0d043de352c1", "address": "0x972c17D0adA071db4a0395505dD3Ad0a80809053", "topics": [ "0x442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e" ], - "data": "0xfa8aacf05ce109561214eec67dbeae25fded0b2c48baeb4ec68a1f7823156ca80000000000000000000000000000000000000000000000000000000000000000", - "logIndex": 8, - "blockHash": "0x99d7d64cbc98c4f9a01278f61a2144c553806a76d86549fa073a3a819f48b162" + "data": "0xa22dcffb04d00a00346784a017a164f58f07902892a27ed7fd0b6d3ffece778e0000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 2, + "blockHash": "0xaf88a614a71840f6b93ae5bc01f5c3c61e479a3e7cf0470dc21a2716b5eb2bb7" } ], - "blockNumber": 207764020, - "cumulativeGasUsed": "2363929", + "blockNumber": 208821798, + "cumulativeGasUsed": "2557364", "status": 1, "byzantium": true }, "args": [ - "Test Token", - "TSTTOKEN", + "Ledgity Token", + "LDY", 18, "75000000000000000000000000" ], "numDeployments": 1, - "solcInputHash": "a1815229c8201677d93c11b319ae0396", - "metadata": "{\"compiler\":{\"version\":\"0.8.20+commit.a1b79de6\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"decimals_\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"maxSupply_\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"supplyAfterMint\",\"type\":\"uint256\"}],\"name\":\"MaxSupplyExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotBurner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotMinter\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"BurnAccessGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"BurnAccessRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MintAccessGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MintAccessRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseApproval\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBurners\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMinters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"grantBurnRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"burnAndMinter\",\"type\":\"address\"}],\"name\":\"grantMintAndBurnRoles\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"grantMintRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseApproval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"isBurner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"revokeBurnRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"revokeMintRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"transferAndCall\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"The total supply can be limited during deployment.\",\"events\":{\"Approval(address,address,uint256)\":{\"details\":\"Emitted when the allowance of a `spender` for an `owner` is set by a call to {approve}. `value` is the new allowance.\"},\"Transfer(address,address,uint256)\":{\"details\":\"Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero.\"}},\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burn(address,uint256)\":{\"details\":\"Alias for BurnFrom for compatibility with the older naming convention.Uses burnFrom for all validation & logic.\",\"params\":{\"account\":\"The address to burn tokens from.\",\"amount\":\"The number of tokens to be burned.\"}},\"burn(uint256)\":{\"details\":\"Uses OZ ERC20 _burn to disallow burning from address(0).Decreases the total supply.\"},\"burnFrom(address,uint256)\":{\"details\":\"Uses OZ ERC20 _burn to disallow burning from address(0).Decreases the total supply.\"},\"decimals()\":{\"details\":\"Returns the number of decimals used in its user representation.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"decreaseApproval(address,uint256)\":{\"details\":\"Exists to be backwards compatible with the older naming convention.\"},\"grantBurnRole(address)\":{\"details\":\"only the owner can call this function.\"},\"grantMintAndBurnRoles(address)\":{\"details\":\"calls public functions so this function does not require access controls. This is handled in the inner functions.\"},\"grantMintRole(address)\":{\"details\":\"only the owner can call this function.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"increaseApproval(address,uint256)\":{\"details\":\"Exists to be backwards compatible with the older naming convention.\"},\"isBurner(address)\":{\"returns\":{\"_0\":\"true if the address is allowed to burn.\"}},\"isMinter(address)\":{\"returns\":{\"_0\":\"true if the address is allowed to mint.\"}},\"maxSupply()\":{\"details\":\"Returns the max supply of the token, 0 if unlimited.\"},\"mint(address,uint256)\":{\"details\":\"Uses OZ ERC20 _mint to disallow minting to address(0).Disallows minting to address(this)Increases the total supply.\",\"params\":{\"account\":\"The address to mint the new tokens to.\",\"amount\":\"The number of tokens to be minted.\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"revokeBurnRole(address)\":{\"details\":\"only the owner can call this function\"},\"revokeMintRole(address)\":{\"details\":\"only the owner can call this function.\"},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferAndCall(address,uint256,bytes)\":{\"params\":{\"amount\":\"The amount of tokens to be transferred\",\"data\":\"bytes Additional data with no specified format, sent in call to `to`\",\"to\":\"The address which you want to transfer to\"},\"returns\":{\"success\":\"true unless throwing\"}},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"}},\"stateVariables\":{\"i_decimals\":{\"details\":\"The number of decimals for the token\"},\"i_maxSupply\":{\"details\":\"The maximum supply of the token, 0 if unlimited\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"acceptOwnership()\":{\"notice\":\"Allows an ownership transfer to be completed by the recipient.\"},\"burn(address,uint256)\":{\"notice\":\"Burns tokens from a given address..\"},\"getBurners()\":{\"notice\":\"Returns all permissioned burners\"},\"getMinters()\":{\"notice\":\"Returns all permissioned minters\"},\"grantBurnRole(address)\":{\"notice\":\"Grants burn role to the given address.\"},\"grantMintAndBurnRoles(address)\":{\"notice\":\"grants both mint and burn roles to `burnAndMinter`.\"},\"grantMintRole(address)\":{\"notice\":\"Grants mint role to the given address.\"},\"isBurner(address)\":{\"notice\":\"Checks whether a given address is a burner for this token.\"},\"isMinter(address)\":{\"notice\":\"Checks whether a given address is a minter for this token.\"},\"mint(address,uint256)\":{\"notice\":\"Mints new tokens for a given address.\"},\"owner()\":{\"notice\":\"Get the current owner\"},\"revokeBurnRole(address)\":{\"notice\":\"Revokes burn role from the given address.\"},\"revokeMintRole(address)\":{\"notice\":\"Revokes mint role for the given address.\"},\"transferAndCall(address,uint256,bytes)\":{\"notice\":\"Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver\"},\"transferOwnership(address)\":{\"notice\":\"Allows an owner to begin transferring ownership to a new address, pending.\"}},\"notice\":\"A basic ERC677 compatible token contract with burn and minting roles.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/LDY.sol\":\"TSTTOKEN\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"./extensions/IERC20Metadata.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20, IERC20Metadata {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\\n // decrementing then incrementing.\\n _balances[to] += amount;\\n }\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n unchecked {\\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\\n _balances[account] += amount;\\n }\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n // Overflow not possible: amount <= accountBalance <= totalSupply.\\n _totalSupply -= amount;\\n }\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"keccak256\":\"0x4ffc0547c02ad22925310c585c0f166f8759e2648a09e9b489100c42f15dd98d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"keccak256\":\"0x0d19410453cda55960a818e02bd7c18952a5c8fe7a3036e81f0d599f34487a7b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xc3ff3f5c4584e1d9a483ad7ced51ab64523201f4e3d3c65293e4ca8aeb77a961\",\"license\":\"MIT\"},\"src/LDY.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IBurnMintERC20} from \\\"./interfaces/IBurnMintERC20.sol\\\";\\nimport {IERC677} from \\\"./interfaces/IERC677.sol\\\";\\n\\nimport {ERC677} from \\\"./libs/ERC677.sol\\\";\\nimport {OwnerIsCreator} from \\\"./libs/OwnerIsCreator.sol\\\";\\n\\nimport {ERC20Burnable} from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport {EnumerableSet} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {IERC165} from \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/**\\n * @title LDY\\n * @dev The $LDY is the utility and governance token of the entire Ledgity ecosystem.\\n *\\n * This contract is taken from the official Chainlink CCIP cross-chain token template:\\n * https://github.com/smartcontractkit/ccip/blob/onchain-release/v1.1.0/contracts/src/v0.8/shared/token/ERC677/BurnMintERC677.sol\\n * \\n * No changes have been made to the original contract; only the imports and folder\\n * structure have been reworked. This was done to eliminate hundreds of unused files\\n * and to import OpenZeppelin libraries directly from their NPM package.\\n *\\n * $LDY token is non-upgradeable, non-pausable, and non-restrictable.\\n *\\n * Specs:\\n * - Name: Ledgity Token\\n * - Symbol: LDY\\n * - Decimals: 18\\n * - Total supply: 75,000,000\\n *\\n * @custom:security-contact security@ledgity.com\\n */\\n\\n/// @notice A basic ERC677 compatible token contract with burn and minting roles.\\n/// @dev The total supply can be limited during deployment.\\ncontract TSTTOKEN is IBurnMintERC20, ERC677, IERC165, ERC20Burnable, OwnerIsCreator {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n error SenderNotMinter(address sender);\\n error SenderNotBurner(address sender);\\n error MaxSupplyExceeded(uint256 supplyAfterMint);\\n\\n event MintAccessGranted(address indexed minter);\\n event BurnAccessGranted(address indexed burner);\\n event MintAccessRevoked(address indexed minter);\\n event BurnAccessRevoked(address indexed burner);\\n\\n // @dev the allowed minter addresses\\n EnumerableSet.AddressSet internal s_minters;\\n // @dev the allowed burner addresses\\n EnumerableSet.AddressSet internal s_burners;\\n\\n /// @dev The number of decimals for the token\\n uint8 internal immutable i_decimals;\\n\\n /// @dev The maximum supply of the token, 0 if unlimited\\n uint256 internal immutable i_maxSupply;\\n\\n constructor(string memory name, string memory symbol, uint8 decimals_, uint256 maxSupply_) ERC677(name, symbol) {\\n i_decimals = decimals_;\\n i_maxSupply = maxSupply_;\\n }\\n\\n function supportsInterface(bytes4 interfaceId) public pure virtual override returns (bool) {\\n return\\n interfaceId == type(IERC20).interfaceId ||\\n interfaceId == type(IERC677).interfaceId ||\\n interfaceId == type(IBurnMintERC20).interfaceId ||\\n interfaceId == type(IERC165).interfaceId;\\n }\\n\\n // ================================================================\\n // | ERC20 |\\n // ================================================================\\n\\n /// @dev Returns the number of decimals used in its user representation.\\n function decimals() public view virtual override returns (uint8) {\\n return i_decimals;\\n }\\n\\n /// @dev Returns the max supply of the token, 0 if unlimited.\\n function maxSupply() public view virtual returns (uint256) {\\n return i_maxSupply;\\n }\\n\\n /// @dev Uses OZ ERC20 _transfer to disallow sending to address(0).\\n /// @dev Disallows sending to address(this)\\n function _transfer(address from, address to, uint256 amount) internal virtual override validAddress(to) {\\n super._transfer(from, to, amount);\\n }\\n\\n /// @dev Uses OZ ERC20 _approve to disallow approving for address(0).\\n /// @dev Disallows approving for address(this)\\n function _approve(address owner, address spender, uint256 amount) internal virtual override validAddress(spender) {\\n super._approve(owner, spender, amount);\\n }\\n\\n /// @dev Exists to be backwards compatible with the older naming convention.\\n function decreaseApproval(address spender, uint256 subtractedValue) external returns (bool success) {\\n return decreaseAllowance(spender, subtractedValue);\\n }\\n\\n /// @dev Exists to be backwards compatible with the older naming convention.\\n function increaseApproval(address spender, uint256 addedValue) external {\\n increaseAllowance(spender, addedValue);\\n }\\n\\n /// @notice Check if recipient is valid (not this contract address).\\n /// @param recipient the account we transfer/approve to.\\n /// @dev Reverts with an empty revert to be compatible with the existing link token when\\n /// the recipient is this contract address.\\n modifier validAddress(address recipient) virtual {\\n // solhint-disable-next-line reason-string, custom-errors\\n if (recipient == address(this)) revert();\\n _;\\n }\\n\\n // ================================================================\\n // | Burning & minting |\\n // ================================================================\\n\\n /// @inheritdoc ERC20Burnable\\n /// @dev Uses OZ ERC20 _burn to disallow burning from address(0).\\n /// @dev Decreases the total supply.\\n function burn(uint256 amount) public override(IBurnMintERC20, ERC20Burnable) onlyBurner {\\n super.burn(amount);\\n }\\n\\n /// @inheritdoc IBurnMintERC20\\n /// @dev Alias for BurnFrom for compatibility with the older naming convention.\\n /// @dev Uses burnFrom for all validation & logic.\\n function burn(address account, uint256 amount) public virtual override {\\n burnFrom(account, amount);\\n }\\n\\n /// @inheritdoc ERC20Burnable\\n /// @dev Uses OZ ERC20 _burn to disallow burning from address(0).\\n /// @dev Decreases the total supply.\\n function burnFrom(address account, uint256 amount) public override(IBurnMintERC20, ERC20Burnable) onlyBurner {\\n super.burnFrom(account, amount);\\n }\\n\\n /// @inheritdoc IBurnMintERC20\\n /// @dev Uses OZ ERC20 _mint to disallow minting to address(0).\\n /// @dev Disallows minting to address(this)\\n /// @dev Increases the total supply.\\n function mint(address account, uint256 amount) external override onlyMinter validAddress(account) {\\n if (i_maxSupply != 0 && totalSupply() + amount > i_maxSupply) revert MaxSupplyExceeded(totalSupply() + amount);\\n\\n _mint(account, amount);\\n }\\n\\n // ================================================================\\n // | Roles |\\n // ================================================================\\n\\n /// @notice grants both mint and burn roles to `burnAndMinter`.\\n /// @dev calls public functions so this function does not require\\n /// access controls. This is handled in the inner functions.\\n function grantMintAndBurnRoles(address burnAndMinter) external {\\n grantMintRole(burnAndMinter);\\n grantBurnRole(burnAndMinter);\\n }\\n\\n /// @notice Grants mint role to the given address.\\n /// @dev only the owner can call this function.\\n function grantMintRole(address minter) public onlyOwner {\\n if (s_minters.add(minter)) {\\n emit MintAccessGranted(minter);\\n }\\n }\\n\\n /// @notice Grants burn role to the given address.\\n /// @dev only the owner can call this function.\\n function grantBurnRole(address burner) public onlyOwner {\\n if (s_burners.add(burner)) {\\n emit BurnAccessGranted(burner);\\n }\\n }\\n\\n /// @notice Revokes mint role for the given address.\\n /// @dev only the owner can call this function.\\n function revokeMintRole(address minter) public onlyOwner {\\n if (s_minters.remove(minter)) {\\n emit MintAccessRevoked(minter);\\n }\\n }\\n\\n /// @notice Revokes burn role from the given address.\\n /// @dev only the owner can call this function\\n function revokeBurnRole(address burner) public onlyOwner {\\n if (s_burners.remove(burner)) {\\n emit BurnAccessRevoked(burner);\\n }\\n }\\n\\n /// @notice Returns all permissioned minters\\n function getMinters() public view returns (address[] memory) {\\n return s_minters.values();\\n }\\n\\n /// @notice Returns all permissioned burners\\n function getBurners() public view returns (address[] memory) {\\n return s_burners.values();\\n }\\n\\n // ================================================================\\n // | Access |\\n // ================================================================\\n\\n /// @notice Checks whether a given address is a minter for this token.\\n /// @return true if the address is allowed to mint.\\n function isMinter(address minter) public view returns (bool) {\\n return s_minters.contains(minter);\\n }\\n\\n /// @notice Checks whether a given address is a burner for this token.\\n /// @return true if the address is allowed to burn.\\n function isBurner(address burner) public view returns (bool) {\\n return s_burners.contains(burner);\\n }\\n\\n /// @notice Checks whether the msg.sender is a permissioned minter for this token\\n /// @dev Reverts with a SenderNotMinter if the check fails\\n modifier onlyMinter() {\\n if (!isMinter(msg.sender)) revert SenderNotMinter(msg.sender);\\n _;\\n }\\n\\n /// @notice Checks whether the msg.sender is a permissioned burner for this token\\n /// @dev Reverts with a SenderNotBurner if the check fails\\n modifier onlyBurner() {\\n if (!isBurner(msg.sender)) revert SenderNotBurner(msg.sender);\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x461c5802d27ff58f95bcfa3f58433792d9fbb9ef8911920edf60547c19cf225d\",\"license\":\"MIT\"},\"src/interfaces/IBurnMintERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IBurnMintERC20 is IERC20 {\\n /// @notice Mints new tokens for a given address.\\n /// @param account The address to mint the new tokens to.\\n /// @param amount The number of tokens to be minted.\\n /// @dev this function increases the total supply.\\n function mint(address account, uint256 amount) external;\\n\\n /// @notice Burns tokens from the sender.\\n /// @param amount The number of tokens to be burned.\\n /// @dev this function decreases the total supply.\\n function burn(uint256 amount) external;\\n\\n /// @notice Burns tokens from a given address..\\n /// @param account The address to burn tokens from.\\n /// @param amount The number of tokens to be burned.\\n /// @dev this function decreases the total supply.\\n function burn(address account, uint256 amount) external;\\n\\n /// @notice Burns tokens from a given address..\\n /// @param account The address to burn tokens from.\\n /// @param amount The number of tokens to be burned.\\n /// @dev this function decreases the total supply.\\n function burnFrom(address account, uint256 amount) external;\\n}\\n\",\"keccak256\":\"0x8adc632df6a61f0ca93c3be6e25b0334247bfe48fc339ce92b85155766b614bb\",\"license\":\"MIT\"},\"src/interfaces/IERC677.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IERC677 {\\n event Transfer(address indexed from, address indexed to, uint256 value, bytes data);\\n\\n /// @notice Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver\\n /// @param to The address which you want to transfer to\\n /// @param amount The amount of tokens to be transferred\\n /// @param data bytes Additional data with no specified format, sent in call to `to`\\n /// @return true unless throwing\\n function transferAndCall(address to, uint256 amount, bytes memory data) external returns (bool);\\n}\\n\",\"keccak256\":\"0x771321adbdab6bec7d27bcd8a46dfea813f1c97d97a7a671fe35cd87744daee4\",\"license\":\"MIT\"},\"src/interfaces/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.6;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(address sender, uint256 amount, bytes calldata data) external;\\n}\",\"keccak256\":\"0xddc2a487ff19419029168dd870fff6ab8075446948a404276edc7d053e6f9f35\",\"license\":\"MIT\"},\"src/interfaces/IOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IOwnable {\\n function owner() external returns (address);\\n\\n function transferOwnership(address recipient) external;\\n\\n function acceptOwnership() external;\\n}\",\"keccak256\":\"0x15a45e18786bd5f5158260f7b225daf428f76c4d34284d851c4e480f66b13f25\",\"license\":\"MIT\"},\"src/libs/ConfirmedOwner.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ConfirmedOwnerWithProposal.sol\\\";\\n\\n/**\\n * @title The ConfirmedOwner contract\\n * @notice A contract with helpers for basic contract ownership.\\n */\\ncontract ConfirmedOwner is ConfirmedOwnerWithProposal {\\n constructor(address newOwner) ConfirmedOwnerWithProposal(newOwner, address(0)) {}\\n}\",\"keccak256\":\"0x57960637d0ac27af34cde3f0aa709e49f8ae109697695ec73117dfb6d8a4271d\",\"license\":\"MIT\"},\"src/libs/ConfirmedOwnerWithProposal.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"../interfaces/IOwnable.sol\\\";\\n\\n/**\\n * @title The ConfirmedOwner contract\\n * @notice A contract with helpers for basic contract ownership.\\n */\\ncontract ConfirmedOwnerWithProposal is IOwnable {\\n address private s_owner;\\n address private s_pendingOwner;\\n\\n event OwnershipTransferRequested(address indexed from, address indexed to);\\n event OwnershipTransferred(address indexed from, address indexed to);\\n\\n constructor(address newOwner, address pendingOwner) {\\n require(newOwner != address(0), \\\"Cannot set owner to zero\\\");\\n\\n s_owner = newOwner;\\n if (pendingOwner != address(0)) {\\n _transferOwnership(pendingOwner);\\n }\\n }\\n\\n /**\\n * @notice Allows an owner to begin transferring ownership to a new address,\\n * pending.\\n */\\n function transferOwnership(address to) public override onlyOwner {\\n _transferOwnership(to);\\n }\\n\\n /**\\n * @notice Allows an ownership transfer to be completed by the recipient.\\n */\\n function acceptOwnership() external override {\\n require(msg.sender == s_pendingOwner, \\\"Must be proposed owner\\\");\\n\\n address oldOwner = s_owner;\\n s_owner = msg.sender;\\n s_pendingOwner = address(0);\\n\\n emit OwnershipTransferred(oldOwner, msg.sender);\\n }\\n\\n /**\\n * @notice Get the current owner\\n */\\n function owner() public view override returns (address) {\\n return s_owner;\\n }\\n\\n /**\\n * @notice validate, transfer ownership, and emit relevant events\\n */\\n function _transferOwnership(address to) private {\\n require(to != msg.sender, \\\"Cannot transfer to self\\\");\\n\\n s_pendingOwner = to;\\n\\n emit OwnershipTransferRequested(s_owner, to);\\n }\\n\\n /**\\n * @notice validate access\\n */\\n function _validateOwnership() internal view {\\n require(msg.sender == s_owner, \\\"Only callable by owner\\\");\\n }\\n\\n /**\\n * @notice Reverts if called by anyone other than the contract owner.\\n */\\n modifier onlyOwner() {\\n _validateOwnership();\\n _;\\n }\\n}\",\"keccak256\":\"0x1a48a2386fff0c1068a2eed4decbf0f53b3ea8a77a088fa0a9f033a1688b967f\",\"license\":\"MIT\"},\"src/libs/ERC677.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.0;\\n\\nimport {IERC677} from \\\"../interfaces/IERC677.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/IERC677Receiver.sol\\\";\\n\\nimport {ERC20} from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\n\\ncontract ERC677 is IERC677, ERC20 {\\n constructor(string memory name, string memory symbol) ERC20(name, symbol) {}\\n\\n /// @inheritdoc IERC677\\n function transferAndCall(address to, uint256 amount, bytes memory data) public returns (bool success) {\\n super.transfer(to, amount);\\n emit Transfer(msg.sender, to, amount, data);\\n if (to.code.length > 0) {\\n IERC677Receiver(to).onTokenTransfer(msg.sender, amount, data);\\n }\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xe18487d77f4f20750733acff95919cd1f40e8dd32cfd9440e46ef88e4933ffbd\",\"license\":\"UNLICENSED\"},\"src/libs/OwnerIsCreator.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ConfirmedOwner} from \\\"./ConfirmedOwner.sol\\\";\\n\\n/// @title The OwnerIsCreator contract\\n/// @notice A contract with helpers for basic contract ownership.\\ncontract OwnerIsCreator is ConfirmedOwner {\\n constructor() ConfirmedOwner(msg.sender) {}\\n}\\n\",\"keccak256\":\"0x895af02d6a3df2930bbb6ec1f2d68118b492ca6e710ba0c34fcb6b574a0906aa\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60c06040523480156200001157600080fd5b5060405162001c2a38038062001c2a833981016040819052620000349162000277565b338060008686818160036200004a838262000391565b50600462000059828262000391565b5050506001600160a01b0384169150620000bc90505760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600580546001600160a01b0319166001600160a01b0384811691909117909155811615620000ef57620000ef8162000106565b50505060ff90911660805260a052506200045d9050565b336001600160a01b03821603620001605760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000b3565b600680546001600160a01b0319166001600160a01b03838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001da57600080fd5b81516001600160401b0380821115620001f757620001f7620001b2565b604051601f8301601f19908116603f01168101908282118183101715620002225762000222620001b2565b816040528381526020925086838588010111156200023f57600080fd5b600091505b8382101562000263578582018301518183018401529082019062000244565b600093810190920192909252949350505050565b600080600080608085870312156200028e57600080fd5b84516001600160401b0380821115620002a657600080fd5b620002b488838901620001c8565b95506020870151915080821115620002cb57600080fd5b50620002da87828801620001c8565b935050604085015160ff81168114620002f257600080fd5b6060959095015193969295505050565b600181811c908216806200031757607f821691505b6020821081036200033857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200038c57600081815260208120601f850160051c81016020861015620003675750805b601f850160051c820191505b81811015620003885782815560010162000373565b5050505b505050565b81516001600160401b03811115620003ad57620003ad620001b2565b620003c581620003be845462000302565b846200033e565b602080601f831160018114620003fd5760008415620003e45750858301515b600019600386901b1c1916600185901b17855562000388565b600085815260208120601f198616915b828110156200042e578886015182559484019460019091019084016200040d565b50858210156200044d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a051611799620004916000396000818161042d01528181610715015261073f0152600061027101526117996000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c806379cc67901161010f578063c2e3273d116100a2578063d73dd62311610071578063d73dd62314610451578063dd62ed3e14610464578063f2fde38b14610477578063f81094f31461048a57600080fd5b8063c2e3273d146103f2578063c630948d14610405578063c64d0ebc14610418578063d5abeb011461042b57600080fd5b80639dc29fac116100de5780639dc29fac146103a6578063a457c2d7146103b9578063a9059cbb146103cc578063aa271e1a146103df57600080fd5b806379cc67901461036857806386fe8b431461037b5780638da5cb5b1461038357806395d89b411461039e57600080fd5b806340c10f19116101875780636618846311610156578063661884631461030f5780636b32810b1461032257806370a082311461033757806379ba50971461036057600080fd5b806340c10f19146102c157806342966c68146102d65780634334614a146102e95780634f5632f8146102fc57600080fd5b806323b872dd116101c357806323b872dd14610257578063313ce5671461026a578063395093511461029b5780634000aea0146102ae57600080fd5b806301ffc9a7146101f557806306fdde031461021d578063095ea7b31461023257806318160ddd14610245575b600080fd5b6102086102033660046113d6565b61049d565b60405190151581526020015b60405180910390f35b61022561050a565b6040516102149190611446565b610208610240366004611475565b61059c565b6002545b604051908152602001610214565b61020861026536600461149f565b6105b4565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610214565b6102086102a9366004611475565b6105d8565b6102086102bc3660046114f1565b6105fa565b6102d46102cf366004611475565b6106d0565b005b6102d46102e43660046115bc565b6107b8565b6102086102f73660046115d5565b6107ec565b6102d461030a3660046115d5565b6107f9565b61020861031d366004611475565b610848565b61032a61085b565b60405161021491906115f0565b6102496103453660046115d5565b6001600160a01b031660009081526020819052604090205490565b6102d461086c565b6102d4610376366004611475565b61091a565b61032a610950565b6005546040516001600160a01b039091168152602001610214565b61022561095c565b6102d46103b4366004611475565b61096b565b6102086103c7366004611475565b610975565b6102086103da366004611475565b6109f0565b6102086103ed3660046115d5565b6109fe565b6102d46104003660046115d5565b610a0b565b6102d46104133660046115d5565b610a5a565b6102d46104263660046115d5565b610a68565b7f0000000000000000000000000000000000000000000000000000000000000000610249565b6102d461045f366004611475565b610ab7565b61024961047236600461163d565b610ac1565b6102d46104853660046115d5565b610aec565b6102d46104983660046115d5565b610afd565b60006001600160e01b031982166336372b0760e01b14806104ce57506001600160e01b03198216630200057560e51b145b806104e957506001600160e01b0319821663e6599b4d60e01b145b8061050457506001600160e01b031982166301ffc9a760e01b145b92915050565b60606003805461051990611670565b80601f016020809104026020016040519081016040528092919081815260200182805461054590611670565b80156105925780601f1061056757610100808354040283529160200191610592565b820191906000526020600020905b81548152906001019060200180831161057557829003601f168201915b5050505050905090565b6000336105aa818585610b4c565b5060019392505050565b6000336105c2858285610b73565b6105cd858585610be7565b506001949350505050565b6000336105aa8185856105eb8383610ac1565b6105f591906116c0565b610b4c565b600061060684846109f0565b50836001600160a01b0316336001600160a01b03167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16858560405161064c9291906116d3565b60405180910390a36001600160a01b0384163b156105aa57604051635260769b60e11b81526001600160a01b0385169063a4c0ed3690610694903390879087906004016116f4565b600060405180830381600087803b1580156106ae57600080fd5b505af11580156106c2573d6000803e3d6000fd5b505050505060019392505050565b6106d9336109fe565b6106fd5760405163e2c8c9d560e01b81523360048201526024015b60405180910390fd5b81306001600160a01b0382160361071357600080fd5b7f00000000000000000000000000000000000000000000000000000000000000001580159061077457507f00000000000000000000000000000000000000000000000000000000000000008261076860025490565b61077291906116c0565b115b156107a9578161078360025490565b61078d91906116c0565b60405163cbbf111360e01b81526004016106f491815260200190565b6107b38383610c08565b505050565b6107c1336107ec565b6107e05760405163c820b10b60e01b81523360048201526024016106f4565b6107e981610cc7565b50565b6000610504600983610cd1565b610801610cf3565b61080c600982610d48565b156107e9576040516001600160a01b038216907f0a675452746933cefe3d74182e78db7afe57ba60eaa4234b5d85e9aa41b0610c90600090a250565b60006108548383610975565b9392505050565b60606108676007610d5d565b905090565b6006546001600160a01b031633146108bf5760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b60448201526064016106f4565b600580546001600160a01b0319808216339081179093556006805490911690556040516001600160a01b03909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b610923336107ec565b6109425760405163c820b10b60e01b81523360048201526024016106f4565b61094c8282610d6a565b5050565b60606108676009610d5d565b60606004805461051990611670565b61094c828261091a565b600033816109838286610ac1565b9050838110156109e35760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016106f4565b6105cd8286868403610b4c565b6000336105aa818585610be7565b6000610504600783610cd1565b610a13610cf3565b610a1e600782610d7f565b156107e9576040516001600160a01b038216907fe46fef8bbff1389d9010703cf8ebb363fb3daf5bf56edc27080b67bc8d9251ea90600090a250565b610a6381610a0b565b6107e9815b610a70610cf3565b610a7b600982610d7f565b156107e9576040516001600160a01b038216907f92308bb7573b2a3d17ddb868b39d8ebec433f3194421abc22d084f89658c9bad90600090a250565b6107b382826105d8565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610af4610cf3565b6107e981610d94565b610b05610cf3565b610b10600782610d48565b156107e9576040516001600160a01b038216907fed998b960f6340d045f620c119730f7aa7995e7425c2401d3a5b64ff998a59e990600090a250565b81306001600160a01b03821603610b6257600080fd5b610b6d848484610e3e565b50505050565b6000610b7f8484610ac1565b90506000198114610b6d5781811015610bda5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106f4565b610b6d8484848403610b4c565b81306001600160a01b03821603610bfd57600080fd5b610b6d848484610f62565b6001600160a01b038216610c5e5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106f4565b8060026000828254610c7091906116c0565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6107e93382611106565b6001600160a01b03811660009081526001830160205260408120541515610854565b6005546001600160a01b03163314610d465760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b60448201526064016106f4565b565b6000610854836001600160a01b038416611238565b606060006108548361132b565b610d75823383610b73565b61094c8282611106565b6000610854836001600160a01b038416611387565b336001600160a01b03821603610dec5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106f4565b600680546001600160a01b0319166001600160a01b03838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b6001600160a01b038316610ea05760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016106f4565b6001600160a01b038216610f015760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016106f4565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b038316610fc65760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016106f4565b6001600160a01b0382166110285760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016106f4565b6001600160a01b038316600090815260208190526040902054818110156110a05760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016106f4565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610b6d565b6001600160a01b0382166111665760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016106f4565b6001600160a01b038216600090815260208190526040902054818110156111da5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016106f4565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6000818152600183016020526040812054801561132157600061125c600183611724565b855490915060009061127090600190611724565b90508181146112d557600086600001828154811061129057611290611737565b90600052602060002001549050808760000184815481106112b3576112b3611737565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806112e6576112e661174d565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610504565b6000915050610504565b60608160000180548060200260200160405190810160405280929190818152602001828054801561137b57602002820191906000526020600020905b815481526020019060010190808311611367575b50505050509050919050565b60008181526001830160205260408120546113ce57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610504565b506000610504565b6000602082840312156113e857600080fd5b81356001600160e01b03198116811461085457600080fd5b6000815180845260005b818110156114265760208185018101518683018201520161140a565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006108546020830184611400565b80356001600160a01b038116811461147057600080fd5b919050565b6000806040838503121561148857600080fd5b61149183611459565b946020939093013593505050565b6000806000606084860312156114b457600080fd5b6114bd84611459565b92506114cb60208501611459565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b60008060006060848603121561150657600080fd5b61150f84611459565b925060208401359150604084013567ffffffffffffffff8082111561153357600080fd5b818601915086601f83011261154757600080fd5b813581811115611559576115596114db565b604051601f8201601f19908116603f01168101908382118183101715611581576115816114db565b8160405282815289602084870101111561159a57600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b6000602082840312156115ce57600080fd5b5035919050565b6000602082840312156115e757600080fd5b61085482611459565b6020808252825182820181905260009190848201906040850190845b818110156116315783516001600160a01b03168352928401929184019160010161160c565b50909695505050505050565b6000806040838503121561165057600080fd5b61165983611459565b915061166760208401611459565b90509250929050565b600181811c9082168061168457607f821691505b6020821081036116a457634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610504576105046116aa565b8281526040602082015260006116ec6040830184611400565b949350505050565b60018060a01b038416815282602082015260606040820152600061171b6060830184611400565b95945050505050565b81810381811115610504576105046116aa565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fdfea26469706673582212205a3a81505b3271adf6e889a8843a188eefdd55c30388fd44e65ed00d036803df64736f6c63430008140033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101f05760003560e01c806379cc67901161010f578063c2e3273d116100a2578063d73dd62311610071578063d73dd62314610451578063dd62ed3e14610464578063f2fde38b14610477578063f81094f31461048a57600080fd5b8063c2e3273d146103f2578063c630948d14610405578063c64d0ebc14610418578063d5abeb011461042b57600080fd5b80639dc29fac116100de5780639dc29fac146103a6578063a457c2d7146103b9578063a9059cbb146103cc578063aa271e1a146103df57600080fd5b806379cc67901461036857806386fe8b431461037b5780638da5cb5b1461038357806395d89b411461039e57600080fd5b806340c10f19116101875780636618846311610156578063661884631461030f5780636b32810b1461032257806370a082311461033757806379ba50971461036057600080fd5b806340c10f19146102c157806342966c68146102d65780634334614a146102e95780634f5632f8146102fc57600080fd5b806323b872dd116101c357806323b872dd14610257578063313ce5671461026a578063395093511461029b5780634000aea0146102ae57600080fd5b806301ffc9a7146101f557806306fdde031461021d578063095ea7b31461023257806318160ddd14610245575b600080fd5b6102086102033660046113d6565b61049d565b60405190151581526020015b60405180910390f35b61022561050a565b6040516102149190611446565b610208610240366004611475565b61059c565b6002545b604051908152602001610214565b61020861026536600461149f565b6105b4565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610214565b6102086102a9366004611475565b6105d8565b6102086102bc3660046114f1565b6105fa565b6102d46102cf366004611475565b6106d0565b005b6102d46102e43660046115bc565b6107b8565b6102086102f73660046115d5565b6107ec565b6102d461030a3660046115d5565b6107f9565b61020861031d366004611475565b610848565b61032a61085b565b60405161021491906115f0565b6102496103453660046115d5565b6001600160a01b031660009081526020819052604090205490565b6102d461086c565b6102d4610376366004611475565b61091a565b61032a610950565b6005546040516001600160a01b039091168152602001610214565b61022561095c565b6102d46103b4366004611475565b61096b565b6102086103c7366004611475565b610975565b6102086103da366004611475565b6109f0565b6102086103ed3660046115d5565b6109fe565b6102d46104003660046115d5565b610a0b565b6102d46104133660046115d5565b610a5a565b6102d46104263660046115d5565b610a68565b7f0000000000000000000000000000000000000000000000000000000000000000610249565b6102d461045f366004611475565b610ab7565b61024961047236600461163d565b610ac1565b6102d46104853660046115d5565b610aec565b6102d46104983660046115d5565b610afd565b60006001600160e01b031982166336372b0760e01b14806104ce57506001600160e01b03198216630200057560e51b145b806104e957506001600160e01b0319821663e6599b4d60e01b145b8061050457506001600160e01b031982166301ffc9a760e01b145b92915050565b60606003805461051990611670565b80601f016020809104026020016040519081016040528092919081815260200182805461054590611670565b80156105925780601f1061056757610100808354040283529160200191610592565b820191906000526020600020905b81548152906001019060200180831161057557829003601f168201915b5050505050905090565b6000336105aa818585610b4c565b5060019392505050565b6000336105c2858285610b73565b6105cd858585610be7565b506001949350505050565b6000336105aa8185856105eb8383610ac1565b6105f591906116c0565b610b4c565b600061060684846109f0565b50836001600160a01b0316336001600160a01b03167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16858560405161064c9291906116d3565b60405180910390a36001600160a01b0384163b156105aa57604051635260769b60e11b81526001600160a01b0385169063a4c0ed3690610694903390879087906004016116f4565b600060405180830381600087803b1580156106ae57600080fd5b505af11580156106c2573d6000803e3d6000fd5b505050505060019392505050565b6106d9336109fe565b6106fd5760405163e2c8c9d560e01b81523360048201526024015b60405180910390fd5b81306001600160a01b0382160361071357600080fd5b7f00000000000000000000000000000000000000000000000000000000000000001580159061077457507f00000000000000000000000000000000000000000000000000000000000000008261076860025490565b61077291906116c0565b115b156107a9578161078360025490565b61078d91906116c0565b60405163cbbf111360e01b81526004016106f491815260200190565b6107b38383610c08565b505050565b6107c1336107ec565b6107e05760405163c820b10b60e01b81523360048201526024016106f4565b6107e981610cc7565b50565b6000610504600983610cd1565b610801610cf3565b61080c600982610d48565b156107e9576040516001600160a01b038216907f0a675452746933cefe3d74182e78db7afe57ba60eaa4234b5d85e9aa41b0610c90600090a250565b60006108548383610975565b9392505050565b60606108676007610d5d565b905090565b6006546001600160a01b031633146108bf5760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b60448201526064016106f4565b600580546001600160a01b0319808216339081179093556006805490911690556040516001600160a01b03909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b610923336107ec565b6109425760405163c820b10b60e01b81523360048201526024016106f4565b61094c8282610d6a565b5050565b60606108676009610d5d565b60606004805461051990611670565b61094c828261091a565b600033816109838286610ac1565b9050838110156109e35760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016106f4565b6105cd8286868403610b4c565b6000336105aa818585610be7565b6000610504600783610cd1565b610a13610cf3565b610a1e600782610d7f565b156107e9576040516001600160a01b038216907fe46fef8bbff1389d9010703cf8ebb363fb3daf5bf56edc27080b67bc8d9251ea90600090a250565b610a6381610a0b565b6107e9815b610a70610cf3565b610a7b600982610d7f565b156107e9576040516001600160a01b038216907f92308bb7573b2a3d17ddb868b39d8ebec433f3194421abc22d084f89658c9bad90600090a250565b6107b382826105d8565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610af4610cf3565b6107e981610d94565b610b05610cf3565b610b10600782610d48565b156107e9576040516001600160a01b038216907fed998b960f6340d045f620c119730f7aa7995e7425c2401d3a5b64ff998a59e990600090a250565b81306001600160a01b03821603610b6257600080fd5b610b6d848484610e3e565b50505050565b6000610b7f8484610ac1565b90506000198114610b6d5781811015610bda5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106f4565b610b6d8484848403610b4c565b81306001600160a01b03821603610bfd57600080fd5b610b6d848484610f62565b6001600160a01b038216610c5e5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106f4565b8060026000828254610c7091906116c0565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6107e93382611106565b6001600160a01b03811660009081526001830160205260408120541515610854565b6005546001600160a01b03163314610d465760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b60448201526064016106f4565b565b6000610854836001600160a01b038416611238565b606060006108548361132b565b610d75823383610b73565b61094c8282611106565b6000610854836001600160a01b038416611387565b336001600160a01b03821603610dec5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106f4565b600680546001600160a01b0319166001600160a01b03838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b6001600160a01b038316610ea05760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016106f4565b6001600160a01b038216610f015760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016106f4565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b038316610fc65760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016106f4565b6001600160a01b0382166110285760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016106f4565b6001600160a01b038316600090815260208190526040902054818110156110a05760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016106f4565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610b6d565b6001600160a01b0382166111665760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016106f4565b6001600160a01b038216600090815260208190526040902054818110156111da5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016106f4565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6000818152600183016020526040812054801561132157600061125c600183611724565b855490915060009061127090600190611724565b90508181146112d557600086600001828154811061129057611290611737565b90600052602060002001549050808760000184815481106112b3576112b3611737565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806112e6576112e661174d565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610504565b6000915050610504565b60608160000180548060200260200160405190810160405280929190818152602001828054801561137b57602002820191906000526020600020905b815481526020019060010190808311611367575b50505050509050919050565b60008181526001830160205260408120546113ce57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610504565b506000610504565b6000602082840312156113e857600080fd5b81356001600160e01b03198116811461085457600080fd5b6000815180845260005b818110156114265760208185018101518683018201520161140a565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006108546020830184611400565b80356001600160a01b038116811461147057600080fd5b919050565b6000806040838503121561148857600080fd5b61149183611459565b946020939093013593505050565b6000806000606084860312156114b457600080fd5b6114bd84611459565b92506114cb60208501611459565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b60008060006060848603121561150657600080fd5b61150f84611459565b925060208401359150604084013567ffffffffffffffff8082111561153357600080fd5b818601915086601f83011261154757600080fd5b813581811115611559576115596114db565b604051601f8201601f19908116603f01168101908382118183101715611581576115816114db565b8160405282815289602084870101111561159a57600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b6000602082840312156115ce57600080fd5b5035919050565b6000602082840312156115e757600080fd5b61085482611459565b6020808252825182820181905260009190848201906040850190845b818110156116315783516001600160a01b03168352928401929184019160010161160c565b50909695505050505050565b6000806040838503121561165057600080fd5b61165983611459565b915061166760208401611459565b90509250929050565b600181811c9082168061168457607f821691505b6020821081036116a457634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610504576105046116aa565b8281526040602082015260006116ec6040830184611400565b949350505050565b60018060a01b038416815282602082015260606040820152600061171b6060830184611400565b95945050505050565b81810381811115610504576105046116aa565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fdfea26469706673582212205a3a81505b3271adf6e889a8843a188eefdd55c30388fd44e65ed00d036803df64736f6c63430008140033", + "solcInputHash": "d8b5802e009f6fee7aed14d8582e28a9", + "metadata": "{\"compiler\":{\"version\":\"0.8.20+commit.a1b79de6\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"decimals_\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"maxSupply_\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"supplyAfterMint\",\"type\":\"uint256\"}],\"name\":\"MaxSupplyExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotBurner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotMinter\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"BurnAccessGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"BurnAccessRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MintAccessGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MintAccessRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseApproval\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBurners\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMinters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"grantBurnRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"burnAndMinter\",\"type\":\"address\"}],\"name\":\"grantMintAndBurnRoles\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"grantMintRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseApproval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"isBurner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"revokeBurnRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"revokeMintRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"transferAndCall\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"The total supply can be limited during deployment.\",\"events\":{\"Approval(address,address,uint256)\":{\"details\":\"Emitted when the allowance of a `spender` for an `owner` is set by a call to {approve}. `value` is the new allowance.\"},\"Transfer(address,address,uint256)\":{\"details\":\"Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero.\"}},\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burn(address,uint256)\":{\"details\":\"Alias for BurnFrom for compatibility with the older naming convention.Uses burnFrom for all validation & logic.\",\"params\":{\"account\":\"The address to burn tokens from.\",\"amount\":\"The number of tokens to be burned.\"}},\"burn(uint256)\":{\"details\":\"Uses OZ ERC20 _burn to disallow burning from address(0).Decreases the total supply.\"},\"burnFrom(address,uint256)\":{\"details\":\"Uses OZ ERC20 _burn to disallow burning from address(0).Decreases the total supply.\"},\"decimals()\":{\"details\":\"Returns the number of decimals used in its user representation.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"decreaseApproval(address,uint256)\":{\"details\":\"Exists to be backwards compatible with the older naming convention.\"},\"grantBurnRole(address)\":{\"details\":\"only the owner can call this function.\"},\"grantMintAndBurnRoles(address)\":{\"details\":\"calls public functions so this function does not require access controls. This is handled in the inner functions.\"},\"grantMintRole(address)\":{\"details\":\"only the owner can call this function.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"increaseApproval(address,uint256)\":{\"details\":\"Exists to be backwards compatible with the older naming convention.\"},\"isBurner(address)\":{\"returns\":{\"_0\":\"true if the address is allowed to burn.\"}},\"isMinter(address)\":{\"returns\":{\"_0\":\"true if the address is allowed to mint.\"}},\"maxSupply()\":{\"details\":\"Returns the max supply of the token, 0 if unlimited.\"},\"mint(address,uint256)\":{\"details\":\"Uses OZ ERC20 _mint to disallow minting to address(0).Disallows minting to address(this)Increases the total supply.\",\"params\":{\"account\":\"The address to mint the new tokens to.\",\"amount\":\"The number of tokens to be minted.\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"revokeBurnRole(address)\":{\"details\":\"only the owner can call this function\"},\"revokeMintRole(address)\":{\"details\":\"only the owner can call this function.\"},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferAndCall(address,uint256,bytes)\":{\"params\":{\"amount\":\"The amount of tokens to be transferred\",\"data\":\"bytes Additional data with no specified format, sent in call to `to`\",\"to\":\"The address which you want to transfer to\"},\"returns\":{\"success\":\"true unless throwing\"}},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"}},\"stateVariables\":{\"i_decimals\":{\"details\":\"The number of decimals for the token\"},\"i_maxSupply\":{\"details\":\"The maximum supply of the token, 0 if unlimited\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"acceptOwnership()\":{\"notice\":\"Allows an ownership transfer to be completed by the recipient.\"},\"burn(address,uint256)\":{\"notice\":\"Burns tokens from a given address..\"},\"getBurners()\":{\"notice\":\"Returns all permissioned burners\"},\"getMinters()\":{\"notice\":\"Returns all permissioned minters\"},\"grantBurnRole(address)\":{\"notice\":\"Grants burn role to the given address.\"},\"grantMintAndBurnRoles(address)\":{\"notice\":\"grants both mint and burn roles to `burnAndMinter`.\"},\"grantMintRole(address)\":{\"notice\":\"Grants mint role to the given address.\"},\"isBurner(address)\":{\"notice\":\"Checks whether a given address is a burner for this token.\"},\"isMinter(address)\":{\"notice\":\"Checks whether a given address is a minter for this token.\"},\"mint(address,uint256)\":{\"notice\":\"Mints new tokens for a given address.\"},\"owner()\":{\"notice\":\"Get the current owner\"},\"revokeBurnRole(address)\":{\"notice\":\"Revokes burn role from the given address.\"},\"revokeMintRole(address)\":{\"notice\":\"Revokes mint role for the given address.\"},\"transferAndCall(address,uint256,bytes)\":{\"notice\":\"Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver\"},\"transferOwnership(address)\":{\"notice\":\"Allows an owner to begin transferring ownership to a new address, pending.\"}},\"notice\":\"A basic ERC677 compatible token contract with burn and minting roles.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/LDY.sol\":\"LDY\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"./extensions/IERC20Metadata.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20, IERC20Metadata {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\\n // decrementing then incrementing.\\n _balances[to] += amount;\\n }\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n unchecked {\\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\\n _balances[account] += amount;\\n }\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n // Overflow not possible: amount <= accountBalance <= totalSupply.\\n _totalSupply -= amount;\\n }\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"keccak256\":\"0x4ffc0547c02ad22925310c585c0f166f8759e2648a09e9b489100c42f15dd98d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"keccak256\":\"0x0d19410453cda55960a818e02bd7c18952a5c8fe7a3036e81f0d599f34487a7b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xc3ff3f5c4584e1d9a483ad7ced51ab64523201f4e3d3c65293e4ca8aeb77a961\",\"license\":\"MIT\"},\"src/LDY.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IBurnMintERC20} from \\\"./interfaces/IBurnMintERC20.sol\\\";\\nimport {IERC677} from \\\"./interfaces/IERC677.sol\\\";\\n\\nimport {ERC677} from \\\"./libs/ERC677.sol\\\";\\nimport {OwnerIsCreator} from \\\"./libs/OwnerIsCreator.sol\\\";\\n\\nimport {ERC20Burnable} from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport {EnumerableSet} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {IERC165} from \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/**\\n * @title LDY\\n * @dev The $LDY is the utility and governance token of the entire Ledgity ecosystem.\\n *\\n * This contract is taken from the official Chainlink CCIP cross-chain token template:\\n * https://github.com/smartcontractkit/ccip/blob/onchain-release/v1.1.0/contracts/src/v0.8/shared/token/ERC677/BurnMintERC677.sol\\n * \\n * No changes have been made to the original contract; only the imports and folder\\n * structure have been reworked. This was done to eliminate hundreds of unused files\\n * and to import OpenZeppelin libraries directly from their NPM package.\\n *\\n * $LDY token is non-upgradeable, non-pausable, and non-restrictable.\\n *\\n * Specs:\\n * - Name: Ledgity Token\\n * - Symbol: LDY\\n * - Decimals: 18\\n * - Total supply: 75,000,000\\n *\\n * @custom:security-contact security@ledgity.com\\n */\\n\\n/// @notice A basic ERC677 compatible token contract with burn and minting roles.\\n/// @dev The total supply can be limited during deployment.\\ncontract LDY is IBurnMintERC20, ERC677, IERC165, ERC20Burnable, OwnerIsCreator {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n error SenderNotMinter(address sender);\\n error SenderNotBurner(address sender);\\n error MaxSupplyExceeded(uint256 supplyAfterMint);\\n\\n event MintAccessGranted(address indexed minter);\\n event BurnAccessGranted(address indexed burner);\\n event MintAccessRevoked(address indexed minter);\\n event BurnAccessRevoked(address indexed burner);\\n\\n // @dev the allowed minter addresses\\n EnumerableSet.AddressSet internal s_minters;\\n // @dev the allowed burner addresses\\n EnumerableSet.AddressSet internal s_burners;\\n\\n /// @dev The number of decimals for the token\\n uint8 internal immutable i_decimals;\\n\\n /// @dev The maximum supply of the token, 0 if unlimited\\n uint256 internal immutable i_maxSupply;\\n\\n constructor(string memory name, string memory symbol, uint8 decimals_, uint256 maxSupply_) ERC677(name, symbol) {\\n i_decimals = decimals_;\\n i_maxSupply = maxSupply_;\\n }\\n\\n function supportsInterface(bytes4 interfaceId) public pure virtual override returns (bool) {\\n return\\n interfaceId == type(IERC20).interfaceId ||\\n interfaceId == type(IERC677).interfaceId ||\\n interfaceId == type(IBurnMintERC20).interfaceId ||\\n interfaceId == type(IERC165).interfaceId;\\n }\\n\\n // ================================================================\\n // | ERC20 |\\n // ================================================================\\n\\n /// @dev Returns the number of decimals used in its user representation.\\n function decimals() public view virtual override returns (uint8) {\\n return i_decimals;\\n }\\n\\n /// @dev Returns the max supply of the token, 0 if unlimited.\\n function maxSupply() public view virtual returns (uint256) {\\n return i_maxSupply;\\n }\\n\\n /// @dev Uses OZ ERC20 _transfer to disallow sending to address(0).\\n /// @dev Disallows sending to address(this)\\n function _transfer(address from, address to, uint256 amount) internal virtual override validAddress(to) {\\n super._transfer(from, to, amount);\\n }\\n\\n /// @dev Uses OZ ERC20 _approve to disallow approving for address(0).\\n /// @dev Disallows approving for address(this)\\n function _approve(address owner, address spender, uint256 amount) internal virtual override validAddress(spender) {\\n super._approve(owner, spender, amount);\\n }\\n\\n /// @dev Exists to be backwards compatible with the older naming convention.\\n function decreaseApproval(address spender, uint256 subtractedValue) external returns (bool success) {\\n return decreaseAllowance(spender, subtractedValue);\\n }\\n\\n /// @dev Exists to be backwards compatible with the older naming convention.\\n function increaseApproval(address spender, uint256 addedValue) external {\\n increaseAllowance(spender, addedValue);\\n }\\n\\n /// @notice Check if recipient is valid (not this contract address).\\n /// @param recipient the account we transfer/approve to.\\n /// @dev Reverts with an empty revert to be compatible with the existing link token when\\n /// the recipient is this contract address.\\n modifier validAddress(address recipient) virtual {\\n // solhint-disable-next-line reason-string, custom-errors\\n if (recipient == address(this)) revert();\\n _;\\n }\\n\\n // ================================================================\\n // | Burning & minting |\\n // ================================================================\\n\\n /// @inheritdoc ERC20Burnable\\n /// @dev Uses OZ ERC20 _burn to disallow burning from address(0).\\n /// @dev Decreases the total supply.\\n function burn(uint256 amount) public override(IBurnMintERC20, ERC20Burnable) onlyBurner {\\n super.burn(amount);\\n }\\n\\n /// @inheritdoc IBurnMintERC20\\n /// @dev Alias for BurnFrom for compatibility with the older naming convention.\\n /// @dev Uses burnFrom for all validation & logic.\\n function burn(address account, uint256 amount) public virtual override {\\n burnFrom(account, amount);\\n }\\n\\n /// @inheritdoc ERC20Burnable\\n /// @dev Uses OZ ERC20 _burn to disallow burning from address(0).\\n /// @dev Decreases the total supply.\\n function burnFrom(address account, uint256 amount) public override(IBurnMintERC20, ERC20Burnable) onlyBurner {\\n super.burnFrom(account, amount);\\n }\\n\\n /// @inheritdoc IBurnMintERC20\\n /// @dev Uses OZ ERC20 _mint to disallow minting to address(0).\\n /// @dev Disallows minting to address(this)\\n /// @dev Increases the total supply.\\n function mint(address account, uint256 amount) external override onlyMinter validAddress(account) {\\n if (i_maxSupply != 0 && totalSupply() + amount > i_maxSupply) revert MaxSupplyExceeded(totalSupply() + amount);\\n\\n _mint(account, amount);\\n }\\n\\n // ================================================================\\n // | Roles |\\n // ================================================================\\n\\n /// @notice grants both mint and burn roles to `burnAndMinter`.\\n /// @dev calls public functions so this function does not require\\n /// access controls. This is handled in the inner functions.\\n function grantMintAndBurnRoles(address burnAndMinter) external {\\n grantMintRole(burnAndMinter);\\n grantBurnRole(burnAndMinter);\\n }\\n\\n /// @notice Grants mint role to the given address.\\n /// @dev only the owner can call this function.\\n function grantMintRole(address minter) public onlyOwner {\\n if (s_minters.add(minter)) {\\n emit MintAccessGranted(minter);\\n }\\n }\\n\\n /// @notice Grants burn role to the given address.\\n /// @dev only the owner can call this function.\\n function grantBurnRole(address burner) public onlyOwner {\\n if (s_burners.add(burner)) {\\n emit BurnAccessGranted(burner);\\n }\\n }\\n\\n /// @notice Revokes mint role for the given address.\\n /// @dev only the owner can call this function.\\n function revokeMintRole(address minter) public onlyOwner {\\n if (s_minters.remove(minter)) {\\n emit MintAccessRevoked(minter);\\n }\\n }\\n\\n /// @notice Revokes burn role from the given address.\\n /// @dev only the owner can call this function\\n function revokeBurnRole(address burner) public onlyOwner {\\n if (s_burners.remove(burner)) {\\n emit BurnAccessRevoked(burner);\\n }\\n }\\n\\n /// @notice Returns all permissioned minters\\n function getMinters() public view returns (address[] memory) {\\n return s_minters.values();\\n }\\n\\n /// @notice Returns all permissioned burners\\n function getBurners() public view returns (address[] memory) {\\n return s_burners.values();\\n }\\n\\n // ================================================================\\n // | Access |\\n // ================================================================\\n\\n /// @notice Checks whether a given address is a minter for this token.\\n /// @return true if the address is allowed to mint.\\n function isMinter(address minter) public view returns (bool) {\\n return s_minters.contains(minter);\\n }\\n\\n /// @notice Checks whether a given address is a burner for this token.\\n /// @return true if the address is allowed to burn.\\n function isBurner(address burner) public view returns (bool) {\\n return s_burners.contains(burner);\\n }\\n\\n /// @notice Checks whether the msg.sender is a permissioned minter for this token\\n /// @dev Reverts with a SenderNotMinter if the check fails\\n modifier onlyMinter() {\\n if (!isMinter(msg.sender)) revert SenderNotMinter(msg.sender);\\n _;\\n }\\n\\n /// @notice Checks whether the msg.sender is a permissioned burner for this token\\n /// @dev Reverts with a SenderNotBurner if the check fails\\n modifier onlyBurner() {\\n if (!isBurner(msg.sender)) revert SenderNotBurner(msg.sender);\\n _;\\n }\\n}\\n\",\"keccak256\":\"0xed068708e5c2e87ad74caa7c73a97bc02a106ea5d62698234754f63933abf6b5\",\"license\":\"MIT\"},\"src/interfaces/IBurnMintERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IBurnMintERC20 is IERC20 {\\n /// @notice Mints new tokens for a given address.\\n /// @param account The address to mint the new tokens to.\\n /// @param amount The number of tokens to be minted.\\n /// @dev this function increases the total supply.\\n function mint(address account, uint256 amount) external;\\n\\n /// @notice Burns tokens from the sender.\\n /// @param amount The number of tokens to be burned.\\n /// @dev this function decreases the total supply.\\n function burn(uint256 amount) external;\\n\\n /// @notice Burns tokens from a given address..\\n /// @param account The address to burn tokens from.\\n /// @param amount The number of tokens to be burned.\\n /// @dev this function decreases the total supply.\\n function burn(address account, uint256 amount) external;\\n\\n /// @notice Burns tokens from a given address..\\n /// @param account The address to burn tokens from.\\n /// @param amount The number of tokens to be burned.\\n /// @dev this function decreases the total supply.\\n function burnFrom(address account, uint256 amount) external;\\n}\\n\",\"keccak256\":\"0x8adc632df6a61f0ca93c3be6e25b0334247bfe48fc339ce92b85155766b614bb\",\"license\":\"MIT\"},\"src/interfaces/IERC677.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IERC677 {\\n event Transfer(address indexed from, address indexed to, uint256 value, bytes data);\\n\\n /// @notice Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver\\n /// @param to The address which you want to transfer to\\n /// @param amount The amount of tokens to be transferred\\n /// @param data bytes Additional data with no specified format, sent in call to `to`\\n /// @return true unless throwing\\n function transferAndCall(address to, uint256 amount, bytes memory data) external returns (bool);\\n}\\n\",\"keccak256\":\"0x771321adbdab6bec7d27bcd8a46dfea813f1c97d97a7a671fe35cd87744daee4\",\"license\":\"MIT\"},\"src/interfaces/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.6;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(address sender, uint256 amount, bytes calldata data) external;\\n}\",\"keccak256\":\"0xddc2a487ff19419029168dd870fff6ab8075446948a404276edc7d053e6f9f35\",\"license\":\"MIT\"},\"src/interfaces/IOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IOwnable {\\n function owner() external returns (address);\\n\\n function transferOwnership(address recipient) external;\\n\\n function acceptOwnership() external;\\n}\",\"keccak256\":\"0x15a45e18786bd5f5158260f7b225daf428f76c4d34284d851c4e480f66b13f25\",\"license\":\"MIT\"},\"src/libs/ConfirmedOwner.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ConfirmedOwnerWithProposal.sol\\\";\\n\\n/**\\n * @title The ConfirmedOwner contract\\n * @notice A contract with helpers for basic contract ownership.\\n */\\ncontract ConfirmedOwner is ConfirmedOwnerWithProposal {\\n constructor(address newOwner) ConfirmedOwnerWithProposal(newOwner, address(0)) {}\\n}\",\"keccak256\":\"0x57960637d0ac27af34cde3f0aa709e49f8ae109697695ec73117dfb6d8a4271d\",\"license\":\"MIT\"},\"src/libs/ConfirmedOwnerWithProposal.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"../interfaces/IOwnable.sol\\\";\\n\\n/**\\n * @title The ConfirmedOwner contract\\n * @notice A contract with helpers for basic contract ownership.\\n */\\ncontract ConfirmedOwnerWithProposal is IOwnable {\\n address private s_owner;\\n address private s_pendingOwner;\\n\\n event OwnershipTransferRequested(address indexed from, address indexed to);\\n event OwnershipTransferred(address indexed from, address indexed to);\\n\\n constructor(address newOwner, address pendingOwner) {\\n require(newOwner != address(0), \\\"Cannot set owner to zero\\\");\\n\\n s_owner = newOwner;\\n if (pendingOwner != address(0)) {\\n _transferOwnership(pendingOwner);\\n }\\n }\\n\\n /**\\n * @notice Allows an owner to begin transferring ownership to a new address,\\n * pending.\\n */\\n function transferOwnership(address to) public override onlyOwner {\\n _transferOwnership(to);\\n }\\n\\n /**\\n * @notice Allows an ownership transfer to be completed by the recipient.\\n */\\n function acceptOwnership() external override {\\n require(msg.sender == s_pendingOwner, \\\"Must be proposed owner\\\");\\n\\n address oldOwner = s_owner;\\n s_owner = msg.sender;\\n s_pendingOwner = address(0);\\n\\n emit OwnershipTransferred(oldOwner, msg.sender);\\n }\\n\\n /**\\n * @notice Get the current owner\\n */\\n function owner() public view override returns (address) {\\n return s_owner;\\n }\\n\\n /**\\n * @notice validate, transfer ownership, and emit relevant events\\n */\\n function _transferOwnership(address to) private {\\n require(to != msg.sender, \\\"Cannot transfer to self\\\");\\n\\n s_pendingOwner = to;\\n\\n emit OwnershipTransferRequested(s_owner, to);\\n }\\n\\n /**\\n * @notice validate access\\n */\\n function _validateOwnership() internal view {\\n require(msg.sender == s_owner, \\\"Only callable by owner\\\");\\n }\\n\\n /**\\n * @notice Reverts if called by anyone other than the contract owner.\\n */\\n modifier onlyOwner() {\\n _validateOwnership();\\n _;\\n }\\n}\",\"keccak256\":\"0x1a48a2386fff0c1068a2eed4decbf0f53b3ea8a77a088fa0a9f033a1688b967f\",\"license\":\"MIT\"},\"src/libs/ERC677.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.0;\\n\\nimport {IERC677} from \\\"../interfaces/IERC677.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/IERC677Receiver.sol\\\";\\n\\nimport {ERC20} from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\n\\ncontract ERC677 is IERC677, ERC20 {\\n constructor(string memory name, string memory symbol) ERC20(name, symbol) {}\\n\\n /// @inheritdoc IERC677\\n function transferAndCall(address to, uint256 amount, bytes memory data) public returns (bool success) {\\n super.transfer(to, amount);\\n emit Transfer(msg.sender, to, amount, data);\\n if (to.code.length > 0) {\\n IERC677Receiver(to).onTokenTransfer(msg.sender, amount, data);\\n }\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xe18487d77f4f20750733acff95919cd1f40e8dd32cfd9440e46ef88e4933ffbd\",\"license\":\"UNLICENSED\"},\"src/libs/OwnerIsCreator.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ConfirmedOwner} from \\\"./ConfirmedOwner.sol\\\";\\n\\n/// @title The OwnerIsCreator contract\\n/// @notice A contract with helpers for basic contract ownership.\\ncontract OwnerIsCreator is ConfirmedOwner {\\n constructor() ConfirmedOwner(msg.sender) {}\\n}\\n\",\"keccak256\":\"0x895af02d6a3df2930bbb6ec1f2d68118b492ca6e710ba0c34fcb6b574a0906aa\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60c06040523480156200001157600080fd5b5060405162001c2a38038062001c2a833981016040819052620000349162000277565b338060008686818160036200004a838262000391565b50600462000059828262000391565b5050506001600160a01b0384169150620000bc90505760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600580546001600160a01b0319166001600160a01b0384811691909117909155811615620000ef57620000ef8162000106565b50505060ff90911660805260a052506200045d9050565b336001600160a01b03821603620001605760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000b3565b600680546001600160a01b0319166001600160a01b03838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001da57600080fd5b81516001600160401b0380821115620001f757620001f7620001b2565b604051601f8301601f19908116603f01168101908282118183101715620002225762000222620001b2565b816040528381526020925086838588010111156200023f57600080fd5b600091505b8382101562000263578582018301518183018401529082019062000244565b600093810190920192909252949350505050565b600080600080608085870312156200028e57600080fd5b84516001600160401b0380821115620002a657600080fd5b620002b488838901620001c8565b95506020870151915080821115620002cb57600080fd5b50620002da87828801620001c8565b935050604085015160ff81168114620002f257600080fd5b6060959095015193969295505050565b600181811c908216806200031757607f821691505b6020821081036200033857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200038c57600081815260208120601f850160051c81016020861015620003675750805b601f850160051c820191505b81811015620003885782815560010162000373565b5050505b505050565b81516001600160401b03811115620003ad57620003ad620001b2565b620003c581620003be845462000302565b846200033e565b602080601f831160018114620003fd5760008415620003e45750858301515b600019600386901b1c1916600185901b17855562000388565b600085815260208120601f198616915b828110156200042e578886015182559484019460019091019084016200040d565b50858210156200044d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a051611799620004916000396000818161042d01528181610715015261073f0152600061027101526117996000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c806379cc67901161010f578063c2e3273d116100a2578063d73dd62311610071578063d73dd62314610451578063dd62ed3e14610464578063f2fde38b14610477578063f81094f31461048a57600080fd5b8063c2e3273d146103f2578063c630948d14610405578063c64d0ebc14610418578063d5abeb011461042b57600080fd5b80639dc29fac116100de5780639dc29fac146103a6578063a457c2d7146103b9578063a9059cbb146103cc578063aa271e1a146103df57600080fd5b806379cc67901461036857806386fe8b431461037b5780638da5cb5b1461038357806395d89b411461039e57600080fd5b806340c10f19116101875780636618846311610156578063661884631461030f5780636b32810b1461032257806370a082311461033757806379ba50971461036057600080fd5b806340c10f19146102c157806342966c68146102d65780634334614a146102e95780634f5632f8146102fc57600080fd5b806323b872dd116101c357806323b872dd14610257578063313ce5671461026a578063395093511461029b5780634000aea0146102ae57600080fd5b806301ffc9a7146101f557806306fdde031461021d578063095ea7b31461023257806318160ddd14610245575b600080fd5b6102086102033660046113d6565b61049d565b60405190151581526020015b60405180910390f35b61022561050a565b6040516102149190611446565b610208610240366004611475565b61059c565b6002545b604051908152602001610214565b61020861026536600461149f565b6105b4565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610214565b6102086102a9366004611475565b6105d8565b6102086102bc3660046114f1565b6105fa565b6102d46102cf366004611475565b6106d0565b005b6102d46102e43660046115bc565b6107b8565b6102086102f73660046115d5565b6107ec565b6102d461030a3660046115d5565b6107f9565b61020861031d366004611475565b610848565b61032a61085b565b60405161021491906115f0565b6102496103453660046115d5565b6001600160a01b031660009081526020819052604090205490565b6102d461086c565b6102d4610376366004611475565b61091a565b61032a610950565b6005546040516001600160a01b039091168152602001610214565b61022561095c565b6102d46103b4366004611475565b61096b565b6102086103c7366004611475565b610975565b6102086103da366004611475565b6109f0565b6102086103ed3660046115d5565b6109fe565b6102d46104003660046115d5565b610a0b565b6102d46104133660046115d5565b610a5a565b6102d46104263660046115d5565b610a68565b7f0000000000000000000000000000000000000000000000000000000000000000610249565b6102d461045f366004611475565b610ab7565b61024961047236600461163d565b610ac1565b6102d46104853660046115d5565b610aec565b6102d46104983660046115d5565b610afd565b60006001600160e01b031982166336372b0760e01b14806104ce57506001600160e01b03198216630200057560e51b145b806104e957506001600160e01b0319821663e6599b4d60e01b145b8061050457506001600160e01b031982166301ffc9a760e01b145b92915050565b60606003805461051990611670565b80601f016020809104026020016040519081016040528092919081815260200182805461054590611670565b80156105925780601f1061056757610100808354040283529160200191610592565b820191906000526020600020905b81548152906001019060200180831161057557829003601f168201915b5050505050905090565b6000336105aa818585610b4c565b5060019392505050565b6000336105c2858285610b73565b6105cd858585610be7565b506001949350505050565b6000336105aa8185856105eb8383610ac1565b6105f591906116c0565b610b4c565b600061060684846109f0565b50836001600160a01b0316336001600160a01b03167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16858560405161064c9291906116d3565b60405180910390a36001600160a01b0384163b156105aa57604051635260769b60e11b81526001600160a01b0385169063a4c0ed3690610694903390879087906004016116f4565b600060405180830381600087803b1580156106ae57600080fd5b505af11580156106c2573d6000803e3d6000fd5b505050505060019392505050565b6106d9336109fe565b6106fd5760405163e2c8c9d560e01b81523360048201526024015b60405180910390fd5b81306001600160a01b0382160361071357600080fd5b7f00000000000000000000000000000000000000000000000000000000000000001580159061077457507f00000000000000000000000000000000000000000000000000000000000000008261076860025490565b61077291906116c0565b115b156107a9578161078360025490565b61078d91906116c0565b60405163cbbf111360e01b81526004016106f491815260200190565b6107b38383610c08565b505050565b6107c1336107ec565b6107e05760405163c820b10b60e01b81523360048201526024016106f4565b6107e981610cc7565b50565b6000610504600983610cd1565b610801610cf3565b61080c600982610d48565b156107e9576040516001600160a01b038216907f0a675452746933cefe3d74182e78db7afe57ba60eaa4234b5d85e9aa41b0610c90600090a250565b60006108548383610975565b9392505050565b60606108676007610d5d565b905090565b6006546001600160a01b031633146108bf5760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b60448201526064016106f4565b600580546001600160a01b0319808216339081179093556006805490911690556040516001600160a01b03909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b610923336107ec565b6109425760405163c820b10b60e01b81523360048201526024016106f4565b61094c8282610d6a565b5050565b60606108676009610d5d565b60606004805461051990611670565b61094c828261091a565b600033816109838286610ac1565b9050838110156109e35760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016106f4565b6105cd8286868403610b4c565b6000336105aa818585610be7565b6000610504600783610cd1565b610a13610cf3565b610a1e600782610d7f565b156107e9576040516001600160a01b038216907fe46fef8bbff1389d9010703cf8ebb363fb3daf5bf56edc27080b67bc8d9251ea90600090a250565b610a6381610a0b565b6107e9815b610a70610cf3565b610a7b600982610d7f565b156107e9576040516001600160a01b038216907f92308bb7573b2a3d17ddb868b39d8ebec433f3194421abc22d084f89658c9bad90600090a250565b6107b382826105d8565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610af4610cf3565b6107e981610d94565b610b05610cf3565b610b10600782610d48565b156107e9576040516001600160a01b038216907fed998b960f6340d045f620c119730f7aa7995e7425c2401d3a5b64ff998a59e990600090a250565b81306001600160a01b03821603610b6257600080fd5b610b6d848484610e3e565b50505050565b6000610b7f8484610ac1565b90506000198114610b6d5781811015610bda5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106f4565b610b6d8484848403610b4c565b81306001600160a01b03821603610bfd57600080fd5b610b6d848484610f62565b6001600160a01b038216610c5e5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106f4565b8060026000828254610c7091906116c0565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6107e93382611106565b6001600160a01b03811660009081526001830160205260408120541515610854565b6005546001600160a01b03163314610d465760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b60448201526064016106f4565b565b6000610854836001600160a01b038416611238565b606060006108548361132b565b610d75823383610b73565b61094c8282611106565b6000610854836001600160a01b038416611387565b336001600160a01b03821603610dec5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106f4565b600680546001600160a01b0319166001600160a01b03838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b6001600160a01b038316610ea05760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016106f4565b6001600160a01b038216610f015760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016106f4565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b038316610fc65760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016106f4565b6001600160a01b0382166110285760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016106f4565b6001600160a01b038316600090815260208190526040902054818110156110a05760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016106f4565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610b6d565b6001600160a01b0382166111665760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016106f4565b6001600160a01b038216600090815260208190526040902054818110156111da5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016106f4565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6000818152600183016020526040812054801561132157600061125c600183611724565b855490915060009061127090600190611724565b90508181146112d557600086600001828154811061129057611290611737565b90600052602060002001549050808760000184815481106112b3576112b3611737565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806112e6576112e661174d565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610504565b6000915050610504565b60608160000180548060200260200160405190810160405280929190818152602001828054801561137b57602002820191906000526020600020905b815481526020019060010190808311611367575b50505050509050919050565b60008181526001830160205260408120546113ce57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610504565b506000610504565b6000602082840312156113e857600080fd5b81356001600160e01b03198116811461085457600080fd5b6000815180845260005b818110156114265760208185018101518683018201520161140a565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006108546020830184611400565b80356001600160a01b038116811461147057600080fd5b919050565b6000806040838503121561148857600080fd5b61149183611459565b946020939093013593505050565b6000806000606084860312156114b457600080fd5b6114bd84611459565b92506114cb60208501611459565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b60008060006060848603121561150657600080fd5b61150f84611459565b925060208401359150604084013567ffffffffffffffff8082111561153357600080fd5b818601915086601f83011261154757600080fd5b813581811115611559576115596114db565b604051601f8201601f19908116603f01168101908382118183101715611581576115816114db565b8160405282815289602084870101111561159a57600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b6000602082840312156115ce57600080fd5b5035919050565b6000602082840312156115e757600080fd5b61085482611459565b6020808252825182820181905260009190848201906040850190845b818110156116315783516001600160a01b03168352928401929184019160010161160c565b50909695505050505050565b6000806040838503121561165057600080fd5b61165983611459565b915061166760208401611459565b90509250929050565b600181811c9082168061168457607f821691505b6020821081036116a457634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610504576105046116aa565b8281526040602082015260006116ec6040830184611400565b949350505050565b60018060a01b038416815282602082015260606040820152600061171b6060830184611400565b95945050505050565b81810381811115610504576105046116aa565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fdfea264697066735822122026bf827ff7c4546d08bc173f7cb82c7ccf3be629370907c1d7e2e74f372b4c0164736f6c63430008140033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101f05760003560e01c806379cc67901161010f578063c2e3273d116100a2578063d73dd62311610071578063d73dd62314610451578063dd62ed3e14610464578063f2fde38b14610477578063f81094f31461048a57600080fd5b8063c2e3273d146103f2578063c630948d14610405578063c64d0ebc14610418578063d5abeb011461042b57600080fd5b80639dc29fac116100de5780639dc29fac146103a6578063a457c2d7146103b9578063a9059cbb146103cc578063aa271e1a146103df57600080fd5b806379cc67901461036857806386fe8b431461037b5780638da5cb5b1461038357806395d89b411461039e57600080fd5b806340c10f19116101875780636618846311610156578063661884631461030f5780636b32810b1461032257806370a082311461033757806379ba50971461036057600080fd5b806340c10f19146102c157806342966c68146102d65780634334614a146102e95780634f5632f8146102fc57600080fd5b806323b872dd116101c357806323b872dd14610257578063313ce5671461026a578063395093511461029b5780634000aea0146102ae57600080fd5b806301ffc9a7146101f557806306fdde031461021d578063095ea7b31461023257806318160ddd14610245575b600080fd5b6102086102033660046113d6565b61049d565b60405190151581526020015b60405180910390f35b61022561050a565b6040516102149190611446565b610208610240366004611475565b61059c565b6002545b604051908152602001610214565b61020861026536600461149f565b6105b4565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610214565b6102086102a9366004611475565b6105d8565b6102086102bc3660046114f1565b6105fa565b6102d46102cf366004611475565b6106d0565b005b6102d46102e43660046115bc565b6107b8565b6102086102f73660046115d5565b6107ec565b6102d461030a3660046115d5565b6107f9565b61020861031d366004611475565b610848565b61032a61085b565b60405161021491906115f0565b6102496103453660046115d5565b6001600160a01b031660009081526020819052604090205490565b6102d461086c565b6102d4610376366004611475565b61091a565b61032a610950565b6005546040516001600160a01b039091168152602001610214565b61022561095c565b6102d46103b4366004611475565b61096b565b6102086103c7366004611475565b610975565b6102086103da366004611475565b6109f0565b6102086103ed3660046115d5565b6109fe565b6102d46104003660046115d5565b610a0b565b6102d46104133660046115d5565b610a5a565b6102d46104263660046115d5565b610a68565b7f0000000000000000000000000000000000000000000000000000000000000000610249565b6102d461045f366004611475565b610ab7565b61024961047236600461163d565b610ac1565b6102d46104853660046115d5565b610aec565b6102d46104983660046115d5565b610afd565b60006001600160e01b031982166336372b0760e01b14806104ce57506001600160e01b03198216630200057560e51b145b806104e957506001600160e01b0319821663e6599b4d60e01b145b8061050457506001600160e01b031982166301ffc9a760e01b145b92915050565b60606003805461051990611670565b80601f016020809104026020016040519081016040528092919081815260200182805461054590611670565b80156105925780601f1061056757610100808354040283529160200191610592565b820191906000526020600020905b81548152906001019060200180831161057557829003601f168201915b5050505050905090565b6000336105aa818585610b4c565b5060019392505050565b6000336105c2858285610b73565b6105cd858585610be7565b506001949350505050565b6000336105aa8185856105eb8383610ac1565b6105f591906116c0565b610b4c565b600061060684846109f0565b50836001600160a01b0316336001600160a01b03167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16858560405161064c9291906116d3565b60405180910390a36001600160a01b0384163b156105aa57604051635260769b60e11b81526001600160a01b0385169063a4c0ed3690610694903390879087906004016116f4565b600060405180830381600087803b1580156106ae57600080fd5b505af11580156106c2573d6000803e3d6000fd5b505050505060019392505050565b6106d9336109fe565b6106fd5760405163e2c8c9d560e01b81523360048201526024015b60405180910390fd5b81306001600160a01b0382160361071357600080fd5b7f00000000000000000000000000000000000000000000000000000000000000001580159061077457507f00000000000000000000000000000000000000000000000000000000000000008261076860025490565b61077291906116c0565b115b156107a9578161078360025490565b61078d91906116c0565b60405163cbbf111360e01b81526004016106f491815260200190565b6107b38383610c08565b505050565b6107c1336107ec565b6107e05760405163c820b10b60e01b81523360048201526024016106f4565b6107e981610cc7565b50565b6000610504600983610cd1565b610801610cf3565b61080c600982610d48565b156107e9576040516001600160a01b038216907f0a675452746933cefe3d74182e78db7afe57ba60eaa4234b5d85e9aa41b0610c90600090a250565b60006108548383610975565b9392505050565b60606108676007610d5d565b905090565b6006546001600160a01b031633146108bf5760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b60448201526064016106f4565b600580546001600160a01b0319808216339081179093556006805490911690556040516001600160a01b03909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b610923336107ec565b6109425760405163c820b10b60e01b81523360048201526024016106f4565b61094c8282610d6a565b5050565b60606108676009610d5d565b60606004805461051990611670565b61094c828261091a565b600033816109838286610ac1565b9050838110156109e35760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016106f4565b6105cd8286868403610b4c565b6000336105aa818585610be7565b6000610504600783610cd1565b610a13610cf3565b610a1e600782610d7f565b156107e9576040516001600160a01b038216907fe46fef8bbff1389d9010703cf8ebb363fb3daf5bf56edc27080b67bc8d9251ea90600090a250565b610a6381610a0b565b6107e9815b610a70610cf3565b610a7b600982610d7f565b156107e9576040516001600160a01b038216907f92308bb7573b2a3d17ddb868b39d8ebec433f3194421abc22d084f89658c9bad90600090a250565b6107b382826105d8565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610af4610cf3565b6107e981610d94565b610b05610cf3565b610b10600782610d48565b156107e9576040516001600160a01b038216907fed998b960f6340d045f620c119730f7aa7995e7425c2401d3a5b64ff998a59e990600090a250565b81306001600160a01b03821603610b6257600080fd5b610b6d848484610e3e565b50505050565b6000610b7f8484610ac1565b90506000198114610b6d5781811015610bda5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106f4565b610b6d8484848403610b4c565b81306001600160a01b03821603610bfd57600080fd5b610b6d848484610f62565b6001600160a01b038216610c5e5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106f4565b8060026000828254610c7091906116c0565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6107e93382611106565b6001600160a01b03811660009081526001830160205260408120541515610854565b6005546001600160a01b03163314610d465760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b60448201526064016106f4565b565b6000610854836001600160a01b038416611238565b606060006108548361132b565b610d75823383610b73565b61094c8282611106565b6000610854836001600160a01b038416611387565b336001600160a01b03821603610dec5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106f4565b600680546001600160a01b0319166001600160a01b03838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b6001600160a01b038316610ea05760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016106f4565b6001600160a01b038216610f015760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016106f4565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b038316610fc65760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016106f4565b6001600160a01b0382166110285760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016106f4565b6001600160a01b038316600090815260208190526040902054818110156110a05760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016106f4565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610b6d565b6001600160a01b0382166111665760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016106f4565b6001600160a01b038216600090815260208190526040902054818110156111da5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016106f4565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6000818152600183016020526040812054801561132157600061125c600183611724565b855490915060009061127090600190611724565b90508181146112d557600086600001828154811061129057611290611737565b90600052602060002001549050808760000184815481106112b3576112b3611737565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806112e6576112e661174d565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610504565b6000915050610504565b60608160000180548060200260200160405190810160405280929190818152602001828054801561137b57602002820191906000526020600020905b815481526020019060010190808311611367575b50505050509050919050565b60008181526001830160205260408120546113ce57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610504565b506000610504565b6000602082840312156113e857600080fd5b81356001600160e01b03198116811461085457600080fd5b6000815180845260005b818110156114265760208185018101518683018201520161140a565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006108546020830184611400565b80356001600160a01b038116811461147057600080fd5b919050565b6000806040838503121561148857600080fd5b61149183611459565b946020939093013593505050565b6000806000606084860312156114b457600080fd5b6114bd84611459565b92506114cb60208501611459565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b60008060006060848603121561150657600080fd5b61150f84611459565b925060208401359150604084013567ffffffffffffffff8082111561153357600080fd5b818601915086601f83011261154757600080fd5b813581811115611559576115596114db565b604051601f8201601f19908116603f01168101908382118183101715611581576115816114db565b8160405282815289602084870101111561159a57600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b6000602082840312156115ce57600080fd5b5035919050565b6000602082840312156115e757600080fd5b61085482611459565b6020808252825182820181905260009190848201906040850190845b818110156116315783516001600160a01b03168352928401929184019160010161160c565b50909695505050505050565b6000806040838503121561165057600080fd5b61165983611459565b915061166760208401611459565b90509250929050565b600181811c9082168061168457607f821691505b6020821081036116a457634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610504576105046116aa565b8281526040602082015260006116ec6040830184611400565b949350505050565b60018060a01b038416815282602082015260606040820152600061171b6060830184611400565b95945050505050565b81810381811115610504576105046116aa565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fdfea264697066735822122026bf827ff7c4546d08bc173f7cb82c7ccf3be629370907c1d7e2e74f372b4c0164736f6c63430008140033", "devdoc": { "details": "The total supply can be limited during deployment.", "events": { @@ -1027,7 +1027,7 @@ "storage": [ { "astId": 15, - "contract": "src/LDY.sol:TSTTOKEN", + "contract": "src/LDY.sol:LDY", "label": "_balances", "offset": 0, "slot": "0", @@ -1035,7 +1035,7 @@ }, { "astId": 21, - "contract": "src/LDY.sol:TSTTOKEN", + "contract": "src/LDY.sol:LDY", "label": "_allowances", "offset": 0, "slot": "1", @@ -1043,7 +1043,7 @@ }, { "astId": 23, - "contract": "src/LDY.sol:TSTTOKEN", + "contract": "src/LDY.sol:LDY", "label": "_totalSupply", "offset": 0, "slot": "2", @@ -1051,7 +1051,7 @@ }, { "astId": 25, - "contract": "src/LDY.sol:TSTTOKEN", + "contract": "src/LDY.sol:LDY", "label": "_name", "offset": 0, "slot": "3", @@ -1059,7 +1059,7 @@ }, { "astId": 27, - "contract": "src/LDY.sol:TSTTOKEN", + "contract": "src/LDY.sol:LDY", "label": "_symbol", "offset": 0, "slot": "4", @@ -1067,7 +1067,7 @@ }, { "astId": 2012, - "contract": "src/LDY.sol:TSTTOKEN", + "contract": "src/LDY.sol:LDY", "label": "s_owner", "offset": 0, "slot": "5", @@ -1075,7 +1075,7 @@ }, { "astId": 2014, - "contract": "src/LDY.sol:TSTTOKEN", + "contract": "src/LDY.sol:LDY", "label": "s_pendingOwner", "offset": 0, "slot": "6", @@ -1083,7 +1083,7 @@ }, { "astId": 1444, - "contract": "src/LDY.sol:TSTTOKEN", + "contract": "src/LDY.sol:LDY", "label": "s_minters", "offset": 0, "slot": "7", @@ -1091,7 +1091,7 @@ }, { "astId": 1447, - "contract": "src/LDY.sol:TSTTOKEN", + "contract": "src/LDY.sol:LDY", "label": "s_burners", "offset": 0, "slot": "9", @@ -1147,7 +1147,7 @@ "members": [ { "astId": 1092, - "contract": "src/LDY.sol:TSTTOKEN", + "contract": "src/LDY.sol:LDY", "label": "_inner", "offset": 0, "slot": "0", @@ -1162,7 +1162,7 @@ "members": [ { "astId": 773, - "contract": "src/LDY.sol:TSTTOKEN", + "contract": "src/LDY.sol:LDY", "label": "_values", "offset": 0, "slot": "0", @@ -1170,7 +1170,7 @@ }, { "astId": 777, - "contract": "src/LDY.sol:TSTTOKEN", + "contract": "src/LDY.sol:LDY", "label": "_indexes", "offset": 0, "slot": "1", diff --git a/hardhat/deployments/arbitrum/solcInputs/a1815229c8201677d93c11b319ae0396.json b/hardhat/deployments/arbitrum/solcInputs/d8b5802e009f6fee7aed14d8582e28a9.json similarity index 84% rename from hardhat/deployments/arbitrum/solcInputs/a1815229c8201677d93c11b319ae0396.json rename to hardhat/deployments/arbitrum/solcInputs/d8b5802e009f6fee7aed14d8582e28a9.json index d646601..b77ec66 100644 --- a/hardhat/deployments/arbitrum/solcInputs/a1815229c8201677d93c11b319ae0396.json +++ b/hardhat/deployments/arbitrum/solcInputs/d8b5802e009f6fee7aed14d8582e28a9.json @@ -35,7 +35,7 @@ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IOwnable {\n function owner() external returns (address);\n\n function transferOwnership(address recipient) external;\n\n function acceptOwnership() external;\n}" }, "src/LDY.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IBurnMintERC20} from \"./interfaces/IBurnMintERC20.sol\";\nimport {IERC677} from \"./interfaces/IERC677.sol\";\n\nimport {ERC677} from \"./libs/ERC677.sol\";\nimport {OwnerIsCreator} from \"./libs/OwnerIsCreator.sol\";\n\nimport {ERC20Burnable} from \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/**\n * @title LDY\n * @dev The $LDY is the utility and governance token of the entire Ledgity ecosystem.\n *\n * This contract is taken from the official Chainlink CCIP cross-chain token template:\n * https://github.com/smartcontractkit/ccip/blob/onchain-release/v1.1.0/contracts/src/v0.8/shared/token/ERC677/BurnMintERC677.sol\n * \n * No changes have been made to the original contract; only the imports and folder\n * structure have been reworked. This was done to eliminate hundreds of unused files\n * and to import OpenZeppelin libraries directly from their NPM package.\n *\n * $LDY token is non-upgradeable, non-pausable, and non-restrictable.\n *\n * Specs:\n * - Name: Ledgity Token\n * - Symbol: LDY\n * - Decimals: 18\n * - Total supply: 75,000,000\n *\n * @custom:security-contact security@ledgity.com\n */\n\n/// @notice A basic ERC677 compatible token contract with burn and minting roles.\n/// @dev The total supply can be limited during deployment.\ncontract TSTTOKEN is IBurnMintERC20, ERC677, IERC165, ERC20Burnable, OwnerIsCreator {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n error SenderNotMinter(address sender);\n error SenderNotBurner(address sender);\n error MaxSupplyExceeded(uint256 supplyAfterMint);\n\n event MintAccessGranted(address indexed minter);\n event BurnAccessGranted(address indexed burner);\n event MintAccessRevoked(address indexed minter);\n event BurnAccessRevoked(address indexed burner);\n\n // @dev the allowed minter addresses\n EnumerableSet.AddressSet internal s_minters;\n // @dev the allowed burner addresses\n EnumerableSet.AddressSet internal s_burners;\n\n /// @dev The number of decimals for the token\n uint8 internal immutable i_decimals;\n\n /// @dev The maximum supply of the token, 0 if unlimited\n uint256 internal immutable i_maxSupply;\n\n constructor(string memory name, string memory symbol, uint8 decimals_, uint256 maxSupply_) ERC677(name, symbol) {\n i_decimals = decimals_;\n i_maxSupply = maxSupply_;\n }\n\n function supportsInterface(bytes4 interfaceId) public pure virtual override returns (bool) {\n return\n interfaceId == type(IERC20).interfaceId ||\n interfaceId == type(IERC677).interfaceId ||\n interfaceId == type(IBurnMintERC20).interfaceId ||\n interfaceId == type(IERC165).interfaceId;\n }\n\n // ================================================================\n // | ERC20 |\n // ================================================================\n\n /// @dev Returns the number of decimals used in its user representation.\n function decimals() public view virtual override returns (uint8) {\n return i_decimals;\n }\n\n /// @dev Returns the max supply of the token, 0 if unlimited.\n function maxSupply() public view virtual returns (uint256) {\n return i_maxSupply;\n }\n\n /// @dev Uses OZ ERC20 _transfer to disallow sending to address(0).\n /// @dev Disallows sending to address(this)\n function _transfer(address from, address to, uint256 amount) internal virtual override validAddress(to) {\n super._transfer(from, to, amount);\n }\n\n /// @dev Uses OZ ERC20 _approve to disallow approving for address(0).\n /// @dev Disallows approving for address(this)\n function _approve(address owner, address spender, uint256 amount) internal virtual override validAddress(spender) {\n super._approve(owner, spender, amount);\n }\n\n /// @dev Exists to be backwards compatible with the older naming convention.\n function decreaseApproval(address spender, uint256 subtractedValue) external returns (bool success) {\n return decreaseAllowance(spender, subtractedValue);\n }\n\n /// @dev Exists to be backwards compatible with the older naming convention.\n function increaseApproval(address spender, uint256 addedValue) external {\n increaseAllowance(spender, addedValue);\n }\n\n /// @notice Check if recipient is valid (not this contract address).\n /// @param recipient the account we transfer/approve to.\n /// @dev Reverts with an empty revert to be compatible with the existing link token when\n /// the recipient is this contract address.\n modifier validAddress(address recipient) virtual {\n // solhint-disable-next-line reason-string, custom-errors\n if (recipient == address(this)) revert();\n _;\n }\n\n // ================================================================\n // | Burning & minting |\n // ================================================================\n\n /// @inheritdoc ERC20Burnable\n /// @dev Uses OZ ERC20 _burn to disallow burning from address(0).\n /// @dev Decreases the total supply.\n function burn(uint256 amount) public override(IBurnMintERC20, ERC20Burnable) onlyBurner {\n super.burn(amount);\n }\n\n /// @inheritdoc IBurnMintERC20\n /// @dev Alias for BurnFrom for compatibility with the older naming convention.\n /// @dev Uses burnFrom for all validation & logic.\n function burn(address account, uint256 amount) public virtual override {\n burnFrom(account, amount);\n }\n\n /// @inheritdoc ERC20Burnable\n /// @dev Uses OZ ERC20 _burn to disallow burning from address(0).\n /// @dev Decreases the total supply.\n function burnFrom(address account, uint256 amount) public override(IBurnMintERC20, ERC20Burnable) onlyBurner {\n super.burnFrom(account, amount);\n }\n\n /// @inheritdoc IBurnMintERC20\n /// @dev Uses OZ ERC20 _mint to disallow minting to address(0).\n /// @dev Disallows minting to address(this)\n /// @dev Increases the total supply.\n function mint(address account, uint256 amount) external override onlyMinter validAddress(account) {\n if (i_maxSupply != 0 && totalSupply() + amount > i_maxSupply) revert MaxSupplyExceeded(totalSupply() + amount);\n\n _mint(account, amount);\n }\n\n // ================================================================\n // | Roles |\n // ================================================================\n\n /// @notice grants both mint and burn roles to `burnAndMinter`.\n /// @dev calls public functions so this function does not require\n /// access controls. This is handled in the inner functions.\n function grantMintAndBurnRoles(address burnAndMinter) external {\n grantMintRole(burnAndMinter);\n grantBurnRole(burnAndMinter);\n }\n\n /// @notice Grants mint role to the given address.\n /// @dev only the owner can call this function.\n function grantMintRole(address minter) public onlyOwner {\n if (s_minters.add(minter)) {\n emit MintAccessGranted(minter);\n }\n }\n\n /// @notice Grants burn role to the given address.\n /// @dev only the owner can call this function.\n function grantBurnRole(address burner) public onlyOwner {\n if (s_burners.add(burner)) {\n emit BurnAccessGranted(burner);\n }\n }\n\n /// @notice Revokes mint role for the given address.\n /// @dev only the owner can call this function.\n function revokeMintRole(address minter) public onlyOwner {\n if (s_minters.remove(minter)) {\n emit MintAccessRevoked(minter);\n }\n }\n\n /// @notice Revokes burn role from the given address.\n /// @dev only the owner can call this function\n function revokeBurnRole(address burner) public onlyOwner {\n if (s_burners.remove(burner)) {\n emit BurnAccessRevoked(burner);\n }\n }\n\n /// @notice Returns all permissioned minters\n function getMinters() public view returns (address[] memory) {\n return s_minters.values();\n }\n\n /// @notice Returns all permissioned burners\n function getBurners() public view returns (address[] memory) {\n return s_burners.values();\n }\n\n // ================================================================\n // | Access |\n // ================================================================\n\n /// @notice Checks whether a given address is a minter for this token.\n /// @return true if the address is allowed to mint.\n function isMinter(address minter) public view returns (bool) {\n return s_minters.contains(minter);\n }\n\n /// @notice Checks whether a given address is a burner for this token.\n /// @return true if the address is allowed to burn.\n function isBurner(address burner) public view returns (bool) {\n return s_burners.contains(burner);\n }\n\n /// @notice Checks whether the msg.sender is a permissioned minter for this token\n /// @dev Reverts with a SenderNotMinter if the check fails\n modifier onlyMinter() {\n if (!isMinter(msg.sender)) revert SenderNotMinter(msg.sender);\n _;\n }\n\n /// @notice Checks whether the msg.sender is a permissioned burner for this token\n /// @dev Reverts with a SenderNotBurner if the check fails\n modifier onlyBurner() {\n if (!isBurner(msg.sender)) revert SenderNotBurner(msg.sender);\n _;\n }\n}\n" + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IBurnMintERC20} from \"./interfaces/IBurnMintERC20.sol\";\nimport {IERC677} from \"./interfaces/IERC677.sol\";\n\nimport {ERC677} from \"./libs/ERC677.sol\";\nimport {OwnerIsCreator} from \"./libs/OwnerIsCreator.sol\";\n\nimport {ERC20Burnable} from \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/**\n * @title LDY\n * @dev The $LDY is the utility and governance token of the entire Ledgity ecosystem.\n *\n * This contract is taken from the official Chainlink CCIP cross-chain token template:\n * https://github.com/smartcontractkit/ccip/blob/onchain-release/v1.1.0/contracts/src/v0.8/shared/token/ERC677/BurnMintERC677.sol\n * \n * No changes have been made to the original contract; only the imports and folder\n * structure have been reworked. This was done to eliminate hundreds of unused files\n * and to import OpenZeppelin libraries directly from their NPM package.\n *\n * $LDY token is non-upgradeable, non-pausable, and non-restrictable.\n *\n * Specs:\n * - Name: Ledgity Token\n * - Symbol: LDY\n * - Decimals: 18\n * - Total supply: 75,000,000\n *\n * @custom:security-contact security@ledgity.com\n */\n\n/// @notice A basic ERC677 compatible token contract with burn and minting roles.\n/// @dev The total supply can be limited during deployment.\ncontract LDY is IBurnMintERC20, ERC677, IERC165, ERC20Burnable, OwnerIsCreator {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n error SenderNotMinter(address sender);\n error SenderNotBurner(address sender);\n error MaxSupplyExceeded(uint256 supplyAfterMint);\n\n event MintAccessGranted(address indexed minter);\n event BurnAccessGranted(address indexed burner);\n event MintAccessRevoked(address indexed minter);\n event BurnAccessRevoked(address indexed burner);\n\n // @dev the allowed minter addresses\n EnumerableSet.AddressSet internal s_minters;\n // @dev the allowed burner addresses\n EnumerableSet.AddressSet internal s_burners;\n\n /// @dev The number of decimals for the token\n uint8 internal immutable i_decimals;\n\n /// @dev The maximum supply of the token, 0 if unlimited\n uint256 internal immutable i_maxSupply;\n\n constructor(string memory name, string memory symbol, uint8 decimals_, uint256 maxSupply_) ERC677(name, symbol) {\n i_decimals = decimals_;\n i_maxSupply = maxSupply_;\n }\n\n function supportsInterface(bytes4 interfaceId) public pure virtual override returns (bool) {\n return\n interfaceId == type(IERC20).interfaceId ||\n interfaceId == type(IERC677).interfaceId ||\n interfaceId == type(IBurnMintERC20).interfaceId ||\n interfaceId == type(IERC165).interfaceId;\n }\n\n // ================================================================\n // | ERC20 |\n // ================================================================\n\n /// @dev Returns the number of decimals used in its user representation.\n function decimals() public view virtual override returns (uint8) {\n return i_decimals;\n }\n\n /// @dev Returns the max supply of the token, 0 if unlimited.\n function maxSupply() public view virtual returns (uint256) {\n return i_maxSupply;\n }\n\n /// @dev Uses OZ ERC20 _transfer to disallow sending to address(0).\n /// @dev Disallows sending to address(this)\n function _transfer(address from, address to, uint256 amount) internal virtual override validAddress(to) {\n super._transfer(from, to, amount);\n }\n\n /// @dev Uses OZ ERC20 _approve to disallow approving for address(0).\n /// @dev Disallows approving for address(this)\n function _approve(address owner, address spender, uint256 amount) internal virtual override validAddress(spender) {\n super._approve(owner, spender, amount);\n }\n\n /// @dev Exists to be backwards compatible with the older naming convention.\n function decreaseApproval(address spender, uint256 subtractedValue) external returns (bool success) {\n return decreaseAllowance(spender, subtractedValue);\n }\n\n /// @dev Exists to be backwards compatible with the older naming convention.\n function increaseApproval(address spender, uint256 addedValue) external {\n increaseAllowance(spender, addedValue);\n }\n\n /// @notice Check if recipient is valid (not this contract address).\n /// @param recipient the account we transfer/approve to.\n /// @dev Reverts with an empty revert to be compatible with the existing link token when\n /// the recipient is this contract address.\n modifier validAddress(address recipient) virtual {\n // solhint-disable-next-line reason-string, custom-errors\n if (recipient == address(this)) revert();\n _;\n }\n\n // ================================================================\n // | Burning & minting |\n // ================================================================\n\n /// @inheritdoc ERC20Burnable\n /// @dev Uses OZ ERC20 _burn to disallow burning from address(0).\n /// @dev Decreases the total supply.\n function burn(uint256 amount) public override(IBurnMintERC20, ERC20Burnable) onlyBurner {\n super.burn(amount);\n }\n\n /// @inheritdoc IBurnMintERC20\n /// @dev Alias for BurnFrom for compatibility with the older naming convention.\n /// @dev Uses burnFrom for all validation & logic.\n function burn(address account, uint256 amount) public virtual override {\n burnFrom(account, amount);\n }\n\n /// @inheritdoc ERC20Burnable\n /// @dev Uses OZ ERC20 _burn to disallow burning from address(0).\n /// @dev Decreases the total supply.\n function burnFrom(address account, uint256 amount) public override(IBurnMintERC20, ERC20Burnable) onlyBurner {\n super.burnFrom(account, amount);\n }\n\n /// @inheritdoc IBurnMintERC20\n /// @dev Uses OZ ERC20 _mint to disallow minting to address(0).\n /// @dev Disallows minting to address(this)\n /// @dev Increases the total supply.\n function mint(address account, uint256 amount) external override onlyMinter validAddress(account) {\n if (i_maxSupply != 0 && totalSupply() + amount > i_maxSupply) revert MaxSupplyExceeded(totalSupply() + amount);\n\n _mint(account, amount);\n }\n\n // ================================================================\n // | Roles |\n // ================================================================\n\n /// @notice grants both mint and burn roles to `burnAndMinter`.\n /// @dev calls public functions so this function does not require\n /// access controls. This is handled in the inner functions.\n function grantMintAndBurnRoles(address burnAndMinter) external {\n grantMintRole(burnAndMinter);\n grantBurnRole(burnAndMinter);\n }\n\n /// @notice Grants mint role to the given address.\n /// @dev only the owner can call this function.\n function grantMintRole(address minter) public onlyOwner {\n if (s_minters.add(minter)) {\n emit MintAccessGranted(minter);\n }\n }\n\n /// @notice Grants burn role to the given address.\n /// @dev only the owner can call this function.\n function grantBurnRole(address burner) public onlyOwner {\n if (s_burners.add(burner)) {\n emit BurnAccessGranted(burner);\n }\n }\n\n /// @notice Revokes mint role for the given address.\n /// @dev only the owner can call this function.\n function revokeMintRole(address minter) public onlyOwner {\n if (s_minters.remove(minter)) {\n emit MintAccessRevoked(minter);\n }\n }\n\n /// @notice Revokes burn role from the given address.\n /// @dev only the owner can call this function\n function revokeBurnRole(address burner) public onlyOwner {\n if (s_burners.remove(burner)) {\n emit BurnAccessRevoked(burner);\n }\n }\n\n /// @notice Returns all permissioned minters\n function getMinters() public view returns (address[] memory) {\n return s_minters.values();\n }\n\n /// @notice Returns all permissioned burners\n function getBurners() public view returns (address[] memory) {\n return s_burners.values();\n }\n\n // ================================================================\n // | Access |\n // ================================================================\n\n /// @notice Checks whether a given address is a minter for this token.\n /// @return true if the address is allowed to mint.\n function isMinter(address minter) public view returns (bool) {\n return s_minters.contains(minter);\n }\n\n /// @notice Checks whether a given address is a burner for this token.\n /// @return true if the address is allowed to burn.\n function isBurner(address burner) public view returns (bool) {\n return s_burners.contains(burner);\n }\n\n /// @notice Checks whether the msg.sender is a permissioned minter for this token\n /// @dev Reverts with a SenderNotMinter if the check fails\n modifier onlyMinter() {\n if (!isMinter(msg.sender)) revert SenderNotMinter(msg.sender);\n _;\n }\n\n /// @notice Checks whether the msg.sender is a permissioned burner for this token\n /// @dev Reverts with a SenderNotBurner if the check fails\n modifier onlyBurner() {\n if (!isBurner(msg.sender)) revert SenderNotBurner(msg.sender);\n _;\n }\n}\n" }, "src/libs/ConfirmedOwner.sol": { "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./ConfirmedOwnerWithProposal.sol\";\n\n/**\n * @title The ConfirmedOwner contract\n * @notice A contract with helpers for basic contract ownership.\n */\ncontract ConfirmedOwner is ConfirmedOwnerWithProposal {\n constructor(address newOwner) ConfirmedOwnerWithProposal(newOwner, address(0)) {}\n}" diff --git a/hardhat/deployments/base/.chainId b/hardhat/deployments/base/.chainId new file mode 100644 index 0000000..2a0c263 --- /dev/null +++ b/hardhat/deployments/base/.chainId @@ -0,0 +1 @@ +8453 \ No newline at end of file diff --git a/hardhat/deployments/base/LDY.json b/hardhat/deployments/base/LDY.json new file mode 100644 index 0000000..c59efe6 --- /dev/null +++ b/hardhat/deployments/base/LDY.json @@ -0,0 +1,1189 @@ +{ + "address": "0x055d20a70eFd45aB839Ae1A39603D0cFDBDd8a13", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimals_", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "maxSupply_", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "supplyAfterMint", + "type": "uint256" + } + ], + "name": "MaxSupplyExceeded", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "SenderNotBurner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "SenderNotMinter", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "burner", + "type": "address" + } + ], + "name": "BurnAccessGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "burner", + "type": "address" + } + ], + "name": "BurnAccessRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "MintAccessGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "MintAccessRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "OwnershipTransferRequested", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burnFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseApproval", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getBurners", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMinters", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "burner", + "type": "address" + } + ], + "name": "grantBurnRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "burnAndMinter", + "type": "address" + } + ], + "name": "grantMintAndBurnRoles", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "grantMintRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseApproval", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "burner", + "type": "address" + } + ], + "name": "isBurner", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "isMinter", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "burner", + "type": "address" + } + ], + "name": "revokeBurnRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "revokeMintRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "transferAndCall", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x3e838a6e2d9c78f17b1c05e1a8aa2836e7a904744a714f7fc894ea39d2768927", + "receipt": { + "to": "0x2E816EA2A7Db3DB4C74298cae0d455f0F800E92A", + "from": "0x65b1B95F7b886c87Eb04E70bfE73D00fc640b046", + "contractAddress": "0x055d20a70eFd45aB839Ae1A39603D0cFDBDd8a13", + "transactionIndex": 25, + "gasUsed": "1574330", + "logsBloom": "0x00000000400000000000000000000000000000000000000000000000040000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000020000000000040000000000000000100000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000200000000000000000000004000000000000000000400000000000000000004000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x3a29c7aabd3f7dfcd36b703fc2f1ea96e9559c833afc845565f95ccc90f90999", + "transactionHash": "0x3e838a6e2d9c78f17b1c05e1a8aa2836e7a904744a714f7fc894ea39d2768927", + "logs": [ + { + "transactionIndex": 25, + "blockNumber": 14153547, + "transactionHash": "0x3e838a6e2d9c78f17b1c05e1a8aa2836e7a904744a714f7fc894ea39d2768927", + "address": "0x2E816EA2A7Db3DB4C74298cae0d455f0F800E92A", + "topics": [ + "0x66753cd2356569ee081232e3be8909b950e0a76c1f8460c3a5e3c2be32b11bed" + ], + "data": "0x0000000000000000000000007cbb62eaa69f79e6873cd1ecb2392971036cfaa4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f4000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001da44c8c9ea1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000001d2a60c06040523480156200001157600080fd5b5060405162001c2a38038062001c2a833981016040819052620000349162000277565b338060008686818160036200004a838262000391565b50600462000059828262000391565b5050506001600160a01b0384169150620000bc90505760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600580546001600160a01b0319166001600160a01b0384811691909117909155811615620000ef57620000ef8162000106565b50505060ff90911660805260a052506200045d9050565b336001600160a01b03821603620001605760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000b3565b600680546001600160a01b0319166001600160a01b03838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001da57600080fd5b81516001600160401b0380821115620001f757620001f7620001b2565b604051601f8301601f19908116603f01168101908282118183101715620002225762000222620001b2565b816040528381526020925086838588010111156200023f57600080fd5b600091505b8382101562000263578582018301518183018401529082019062000244565b600093810190920192909252949350505050565b600080600080608085870312156200028e57600080fd5b84516001600160401b0380821115620002a657600080fd5b620002b488838901620001c8565b95506020870151915080821115620002cb57600080fd5b50620002da87828801620001c8565b935050604085015160ff81168114620002f257600080fd5b6060959095015193969295505050565b600181811c908216806200031757607f821691505b6020821081036200033857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200038c57600081815260208120601f850160051c81016020861015620003675750805b601f850160051c820191505b81811015620003885782815560010162000373565b5050505b505050565b81516001600160401b03811115620003ad57620003ad620001b2565b620003c581620003be845462000302565b846200033e565b602080601f831160018114620003fd5760008415620003e45750858301515b600019600386901b1c1916600185901b17855562000388565b600085815260208120601f198616915b828110156200042e578886015182559484019460019091019084016200040d565b50858210156200044d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a051611799620004916000396000818161042d01528181610715015261073f0152600061027101526117996000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c806379cc67901161010f578063c2e3273d116100a2578063d73dd62311610071578063d73dd62314610451578063dd62ed3e14610464578063f2fde38b14610477578063f81094f31461048a57600080fd5b8063c2e3273d146103f2578063c630948d14610405578063c64d0ebc14610418578063d5abeb011461042b57600080fd5b80639dc29fac116100de5780639dc29fac146103a6578063a457c2d7146103b9578063a9059cbb146103cc578063aa271e1a146103df57600080fd5b806379cc67901461036857806386fe8b431461037b5780638da5cb5b1461038357806395d89b411461039e57600080fd5b806340c10f19116101875780636618846311610156578063661884631461030f5780636b32810b1461032257806370a082311461033757806379ba50971461036057600080fd5b806340c10f19146102c157806342966c68146102d65780634334614a146102e95780634f5632f8146102fc57600080fd5b806323b872dd116101c357806323b872dd14610257578063313ce5671461026a578063395093511461029b5780634000aea0146102ae57600080fd5b806301ffc9a7146101f557806306fdde031461021d578063095ea7b31461023257806318160ddd14610245575b600080fd5b6102086102033660046113d6565b61049d565b60405190151581526020015b60405180910390f35b61022561050a565b6040516102149190611446565b610208610240366004611475565b61059c565b6002545b604051908152602001610214565b61020861026536600461149f565b6105b4565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610214565b6102086102a9366004611475565b6105d8565b6102086102bc3660046114f1565b6105fa565b6102d46102cf366004611475565b6106d0565b005b6102d46102e43660046115bc565b6107b8565b6102086102f73660046115d5565b6107ec565b6102d461030a3660046115d5565b6107f9565b61020861031d366004611475565b610848565b61032a61085b565b60405161021491906115f0565b6102496103453660046115d5565b6001600160a01b031660009081526020819052604090205490565b6102d461086c565b6102d4610376366004611475565b61091a565b61032a610950565b6005546040516001600160a01b039091168152602001610214565b61022561095c565b6102d46103b4366004611475565b61096b565b6102086103c7366004611475565b610975565b6102086103da366004611475565b6109f0565b6102086103ed3660046115d5565b6109fe565b6102d46104003660046115d5565b610a0b565b6102d46104133660046115d5565b610a5a565b6102d46104263660046115d5565b610a68565b7f0000000000000000000000000000000000000000000000000000000000000000610249565b6102d461045f366004611475565b610ab7565b61024961047236600461163d565b610ac1565b6102d46104853660046115d5565b610aec565b6102d46104983660046115d5565b610afd565b60006001600160e01b031982166336372b0760e01b14806104ce57506001600160e01b03198216630200057560e51b145b806104e957506001600160e01b0319821663e6599b4d60e01b145b8061050457506001600160e01b031982166301ffc9a760e01b145b92915050565b60606003805461051990611670565b80601f016020809104026020016040519081016040528092919081815260200182805461054590611670565b80156105925780601f1061056757610100808354040283529160200191610592565b820191906000526020600020905b81548152906001019060200180831161057557829003601f168201915b5050505050905090565b6000336105aa818585610b4c565b5060019392505050565b6000336105c2858285610b73565b6105cd858585610be7565b506001949350505050565b6000336105aa8185856105eb8383610ac1565b6105f591906116c0565b610b4c565b600061060684846109f0565b50836001600160a01b0316336001600160a01b03167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16858560405161064c9291906116d3565b60405180910390a36001600160a01b0384163b156105aa57604051635260769b60e11b81526001600160a01b0385169063a4c0ed3690610694903390879087906004016116f4565b600060405180830381600087803b1580156106ae57600080fd5b505af11580156106c2573d6000803e3d6000fd5b505050505060019392505050565b6106d9336109fe565b6106fd5760405163e2c8c9d560e01b81523360048201526024015b60405180910390fd5b81306001600160a01b0382160361071357600080fd5b7f00000000000000000000000000000000000000000000000000000000000000001580159061077457507f00000000000000000000000000000000000000000000000000000000000000008261076860025490565b61077291906116c0565b115b156107a9578161078360025490565b61078d91906116c0565b60405163cbbf111360e01b81526004016106f491815260200190565b6107b38383610c08565b505050565b6107c1336107ec565b6107e05760405163c820b10b60e01b81523360048201526024016106f4565b6107e981610cc7565b50565b6000610504600983610cd1565b610801610cf3565b61080c600982610d48565b156107e9576040516001600160a01b038216907f0a675452746933cefe3d74182e78db7afe57ba60eaa4234b5d85e9aa41b0610c90600090a250565b60006108548383610975565b9392505050565b60606108676007610d5d565b905090565b6006546001600160a01b031633146108bf5760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b60448201526064016106f4565b600580546001600160a01b0319808216339081179093556006805490911690556040516001600160a01b03909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b610923336107ec565b6109425760405163c820b10b60e01b81523360048201526024016106f4565b61094c8282610d6a565b5050565b60606108676009610d5d565b60606004805461051990611670565b61094c828261091a565b600033816109838286610ac1565b9050838110156109e35760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016106f4565b6105cd8286868403610b4c565b6000336105aa818585610be7565b6000610504600783610cd1565b610a13610cf3565b610a1e600782610d7f565b156107e9576040516001600160a01b038216907fe46fef8bbff1389d9010703cf8ebb363fb3daf5bf56edc27080b67bc8d9251ea90600090a250565b610a6381610a0b565b6107e9815b610a70610cf3565b610a7b600982610d7f565b156107e9576040516001600160a01b038216907f92308bb7573b2a3d17ddb868b39d8ebec433f3194421abc22d084f89658c9bad90600090a250565b6107b382826105d8565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610af4610cf3565b6107e981610d94565b610b05610cf3565b610b10600782610d48565b156107e9576040516001600160a01b038216907fed998b960f6340d045f620c119730f7aa7995e7425c2401d3a5b64ff998a59e990600090a250565b81306001600160a01b03821603610b6257600080fd5b610b6d848484610e3e565b50505050565b6000610b7f8484610ac1565b90506000198114610b6d5781811015610bda5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106f4565b610b6d8484848403610b4c565b81306001600160a01b03821603610bfd57600080fd5b610b6d848484610f62565b6001600160a01b038216610c5e5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106f4565b8060026000828254610c7091906116c0565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6107e93382611106565b6001600160a01b03811660009081526001830160205260408120541515610854565b6005546001600160a01b03163314610d465760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b60448201526064016106f4565b565b6000610854836001600160a01b038416611238565b606060006108548361132b565b610d75823383610b73565b61094c8282611106565b6000610854836001600160a01b038416611387565b336001600160a01b03821603610dec5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106f4565b600680546001600160a01b0319166001600160a01b03838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b6001600160a01b038316610ea05760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016106f4565b6001600160a01b038216610f015760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016106f4565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b038316610fc65760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016106f4565b6001600160a01b0382166110285760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016106f4565b6001600160a01b038316600090815260208190526040902054818110156110a05760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016106f4565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610b6d565b6001600160a01b0382166111665760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016106f4565b6001600160a01b038216600090815260208190526040902054818110156111da5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016106f4565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6000818152600183016020526040812054801561132157600061125c600183611724565b855490915060009061127090600190611724565b90508181146112d557600086600001828154811061129057611290611737565b90600052602060002001549050808760000184815481106112b3576112b3611737565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806112e6576112e661174d565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610504565b6000915050610504565b60608160000180548060200260200160405190810160405280929190818152602001828054801561137b57602002820191906000526020600020905b815481526020019060010190808311611367575b50505050509050919050565b60008181526001830160205260408120546113ce57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610504565b506000610504565b6000602082840312156113e857600080fd5b81356001600160e01b03198116811461085457600080fd5b6000815180845260005b818110156114265760208185018101518683018201520161140a565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006108546020830184611400565b80356001600160a01b038116811461147057600080fd5b919050565b6000806040838503121561148857600080fd5b61149183611459565b946020939093013593505050565b6000806000606084860312156114b457600080fd5b6114bd84611459565b92506114cb60208501611459565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b60008060006060848603121561150657600080fd5b61150f84611459565b925060208401359150604084013567ffffffffffffffff8082111561153357600080fd5b818601915086601f83011261154757600080fd5b813581811115611559576115596114db565b604051601f8201601f19908116603f01168101908382118183101715611581576115816114db565b8160405282815289602084870101111561159a57600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b6000602082840312156115ce57600080fd5b5035919050565b6000602082840312156115e757600080fd5b61085482611459565b6020808252825182820181905260009190848201906040850190845b818110156116315783516001600160a01b03168352928401929184019160010161160c565b50909695505050505050565b6000806040838503121561165057600080fd5b61165983611459565b915061166760208401611459565b90509250929050565b600181811c9082168061168457607f821691505b6020821081036116a457634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610504576105046116aa565b8281526040602082015260006116ec6040830184611400565b949350505050565b60018060a01b038416815282602082015260606040820152600061171b6060830184611400565b95945050505050565b81810381811115610504576105046116aa565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fdfea264697066735822122026bf827ff7c4546d08bc173f7cb82c7ccf3be629370907c1d7e2e74f372b4c0164736f6c63430008140033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000003e09de2596099e2b000000000000000000000000000000000000000000000000000000000000000000000d4c65646769747920546f6b656e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034c445900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008200000000000000000000000065b1b95f7b886c87eb04e70bfe73d00fc640b0460000000000000000000000000000000000000000000000000000000000000000017354c6e407f9addf54764bdd8ea6c191e4fb0a6ab39d7cdfc40a7aecad7990232ef20d3954daed8042cab64b62ffc07d81a70315c67059b68a161977c25006f01f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065b1b95f7b886c87eb04e70bfe73d00fc640b0460000000000000000000000000000000000000000000000000000000000000002", + "logIndex": 78, + "blockHash": "0x3a29c7aabd3f7dfcd36b703fc2f1ea96e9559c833afc845565f95ccc90f90999" + }, + { + "transactionIndex": 25, + "blockNumber": 14153547, + "transactionHash": "0x3e838a6e2d9c78f17b1c05e1a8aa2836e7a904744a714f7fc894ea39d2768927", + "address": "0x2E816EA2A7Db3DB4C74298cae0d455f0F800E92A", + "topics": [ + "0x4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b511" + ], + "data": "0x000000000000000000000000055d20a70efd45ab839ae1a39603d0cfdbdd8a13", + "logIndex": 79, + "blockHash": "0x3a29c7aabd3f7dfcd36b703fc2f1ea96e9559c833afc845565f95ccc90f90999" + }, + { + "transactionIndex": 25, + "blockNumber": 14153547, + "transactionHash": "0x3e838a6e2d9c78f17b1c05e1a8aa2836e7a904744a714f7fc894ea39d2768927", + "address": "0x2E816EA2A7Db3DB4C74298cae0d455f0F800E92A", + "topics": [ + "0x442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e" + ], + "data": "0xe3a759ffca53c81ebf9dbc1a50cc07eac8f23f96ebda47f7fd7c109a9703ed520000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 80, + "blockHash": "0x3a29c7aabd3f7dfcd36b703fc2f1ea96e9559c833afc845565f95ccc90f90999" + } + ], + "blockNumber": 14153547, + "cumulativeGasUsed": "5005795", + "status": 1, + "byzantium": true + }, + "args": [ + "Ledgity Token", + "LDY", + 18, + "75000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "d8b5802e009f6fee7aed14d8582e28a9", + "metadata": "{\"compiler\":{\"version\":\"0.8.20+commit.a1b79de6\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"decimals_\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"maxSupply_\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"supplyAfterMint\",\"type\":\"uint256\"}],\"name\":\"MaxSupplyExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotBurner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotMinter\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"BurnAccessGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"BurnAccessRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MintAccessGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MintAccessRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseApproval\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBurners\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMinters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"grantBurnRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"burnAndMinter\",\"type\":\"address\"}],\"name\":\"grantMintAndBurnRoles\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"grantMintRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseApproval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"isBurner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"revokeBurnRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"revokeMintRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"transferAndCall\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"The total supply can be limited during deployment.\",\"events\":{\"Approval(address,address,uint256)\":{\"details\":\"Emitted when the allowance of a `spender` for an `owner` is set by a call to {approve}. `value` is the new allowance.\"},\"Transfer(address,address,uint256)\":{\"details\":\"Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero.\"}},\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burn(address,uint256)\":{\"details\":\"Alias for BurnFrom for compatibility with the older naming convention.Uses burnFrom for all validation & logic.\",\"params\":{\"account\":\"The address to burn tokens from.\",\"amount\":\"The number of tokens to be burned.\"}},\"burn(uint256)\":{\"details\":\"Uses OZ ERC20 _burn to disallow burning from address(0).Decreases the total supply.\"},\"burnFrom(address,uint256)\":{\"details\":\"Uses OZ ERC20 _burn to disallow burning from address(0).Decreases the total supply.\"},\"decimals()\":{\"details\":\"Returns the number of decimals used in its user representation.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"decreaseApproval(address,uint256)\":{\"details\":\"Exists to be backwards compatible with the older naming convention.\"},\"grantBurnRole(address)\":{\"details\":\"only the owner can call this function.\"},\"grantMintAndBurnRoles(address)\":{\"details\":\"calls public functions so this function does not require access controls. This is handled in the inner functions.\"},\"grantMintRole(address)\":{\"details\":\"only the owner can call this function.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"increaseApproval(address,uint256)\":{\"details\":\"Exists to be backwards compatible with the older naming convention.\"},\"isBurner(address)\":{\"returns\":{\"_0\":\"true if the address is allowed to burn.\"}},\"isMinter(address)\":{\"returns\":{\"_0\":\"true if the address is allowed to mint.\"}},\"maxSupply()\":{\"details\":\"Returns the max supply of the token, 0 if unlimited.\"},\"mint(address,uint256)\":{\"details\":\"Uses OZ ERC20 _mint to disallow minting to address(0).Disallows minting to address(this)Increases the total supply.\",\"params\":{\"account\":\"The address to mint the new tokens to.\",\"amount\":\"The number of tokens to be minted.\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"revokeBurnRole(address)\":{\"details\":\"only the owner can call this function\"},\"revokeMintRole(address)\":{\"details\":\"only the owner can call this function.\"},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferAndCall(address,uint256,bytes)\":{\"params\":{\"amount\":\"The amount of tokens to be transferred\",\"data\":\"bytes Additional data with no specified format, sent in call to `to`\",\"to\":\"The address which you want to transfer to\"},\"returns\":{\"success\":\"true unless throwing\"}},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"}},\"stateVariables\":{\"i_decimals\":{\"details\":\"The number of decimals for the token\"},\"i_maxSupply\":{\"details\":\"The maximum supply of the token, 0 if unlimited\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"acceptOwnership()\":{\"notice\":\"Allows an ownership transfer to be completed by the recipient.\"},\"burn(address,uint256)\":{\"notice\":\"Burns tokens from a given address..\"},\"getBurners()\":{\"notice\":\"Returns all permissioned burners\"},\"getMinters()\":{\"notice\":\"Returns all permissioned minters\"},\"grantBurnRole(address)\":{\"notice\":\"Grants burn role to the given address.\"},\"grantMintAndBurnRoles(address)\":{\"notice\":\"grants both mint and burn roles to `burnAndMinter`.\"},\"grantMintRole(address)\":{\"notice\":\"Grants mint role to the given address.\"},\"isBurner(address)\":{\"notice\":\"Checks whether a given address is a burner for this token.\"},\"isMinter(address)\":{\"notice\":\"Checks whether a given address is a minter for this token.\"},\"mint(address,uint256)\":{\"notice\":\"Mints new tokens for a given address.\"},\"owner()\":{\"notice\":\"Get the current owner\"},\"revokeBurnRole(address)\":{\"notice\":\"Revokes burn role from the given address.\"},\"revokeMintRole(address)\":{\"notice\":\"Revokes mint role for the given address.\"},\"transferAndCall(address,uint256,bytes)\":{\"notice\":\"Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver\"},\"transferOwnership(address)\":{\"notice\":\"Allows an owner to begin transferring ownership to a new address, pending.\"}},\"notice\":\"A basic ERC677 compatible token contract with burn and minting roles.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/LDY.sol\":\"LDY\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"./extensions/IERC20Metadata.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20, IERC20Metadata {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\\n // decrementing then incrementing.\\n _balances[to] += amount;\\n }\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n unchecked {\\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\\n _balances[account] += amount;\\n }\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n // Overflow not possible: amount <= accountBalance <= totalSupply.\\n _totalSupply -= amount;\\n }\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"keccak256\":\"0x4ffc0547c02ad22925310c585c0f166f8759e2648a09e9b489100c42f15dd98d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"keccak256\":\"0x0d19410453cda55960a818e02bd7c18952a5c8fe7a3036e81f0d599f34487a7b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xc3ff3f5c4584e1d9a483ad7ced51ab64523201f4e3d3c65293e4ca8aeb77a961\",\"license\":\"MIT\"},\"src/LDY.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IBurnMintERC20} from \\\"./interfaces/IBurnMintERC20.sol\\\";\\nimport {IERC677} from \\\"./interfaces/IERC677.sol\\\";\\n\\nimport {ERC677} from \\\"./libs/ERC677.sol\\\";\\nimport {OwnerIsCreator} from \\\"./libs/OwnerIsCreator.sol\\\";\\n\\nimport {ERC20Burnable} from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport {EnumerableSet} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {IERC165} from \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/**\\n * @title LDY\\n * @dev The $LDY is the utility and governance token of the entire Ledgity ecosystem.\\n *\\n * This contract is taken from the official Chainlink CCIP cross-chain token template:\\n * https://github.com/smartcontractkit/ccip/blob/onchain-release/v1.1.0/contracts/src/v0.8/shared/token/ERC677/BurnMintERC677.sol\\n * \\n * No changes have been made to the original contract; only the imports and folder\\n * structure have been reworked. This was done to eliminate hundreds of unused files\\n * and to import OpenZeppelin libraries directly from their NPM package.\\n *\\n * $LDY token is non-upgradeable, non-pausable, and non-restrictable.\\n *\\n * Specs:\\n * - Name: Ledgity Token\\n * - Symbol: LDY\\n * - Decimals: 18\\n * - Total supply: 75,000,000\\n *\\n * @custom:security-contact security@ledgity.com\\n */\\n\\n/// @notice A basic ERC677 compatible token contract with burn and minting roles.\\n/// @dev The total supply can be limited during deployment.\\ncontract LDY is IBurnMintERC20, ERC677, IERC165, ERC20Burnable, OwnerIsCreator {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n error SenderNotMinter(address sender);\\n error SenderNotBurner(address sender);\\n error MaxSupplyExceeded(uint256 supplyAfterMint);\\n\\n event MintAccessGranted(address indexed minter);\\n event BurnAccessGranted(address indexed burner);\\n event MintAccessRevoked(address indexed minter);\\n event BurnAccessRevoked(address indexed burner);\\n\\n // @dev the allowed minter addresses\\n EnumerableSet.AddressSet internal s_minters;\\n // @dev the allowed burner addresses\\n EnumerableSet.AddressSet internal s_burners;\\n\\n /// @dev The number of decimals for the token\\n uint8 internal immutable i_decimals;\\n\\n /// @dev The maximum supply of the token, 0 if unlimited\\n uint256 internal immutable i_maxSupply;\\n\\n constructor(string memory name, string memory symbol, uint8 decimals_, uint256 maxSupply_) ERC677(name, symbol) {\\n i_decimals = decimals_;\\n i_maxSupply = maxSupply_;\\n }\\n\\n function supportsInterface(bytes4 interfaceId) public pure virtual override returns (bool) {\\n return\\n interfaceId == type(IERC20).interfaceId ||\\n interfaceId == type(IERC677).interfaceId ||\\n interfaceId == type(IBurnMintERC20).interfaceId ||\\n interfaceId == type(IERC165).interfaceId;\\n }\\n\\n // ================================================================\\n // | ERC20 |\\n // ================================================================\\n\\n /// @dev Returns the number of decimals used in its user representation.\\n function decimals() public view virtual override returns (uint8) {\\n return i_decimals;\\n }\\n\\n /// @dev Returns the max supply of the token, 0 if unlimited.\\n function maxSupply() public view virtual returns (uint256) {\\n return i_maxSupply;\\n }\\n\\n /// @dev Uses OZ ERC20 _transfer to disallow sending to address(0).\\n /// @dev Disallows sending to address(this)\\n function _transfer(address from, address to, uint256 amount) internal virtual override validAddress(to) {\\n super._transfer(from, to, amount);\\n }\\n\\n /// @dev Uses OZ ERC20 _approve to disallow approving for address(0).\\n /// @dev Disallows approving for address(this)\\n function _approve(address owner, address spender, uint256 amount) internal virtual override validAddress(spender) {\\n super._approve(owner, spender, amount);\\n }\\n\\n /// @dev Exists to be backwards compatible with the older naming convention.\\n function decreaseApproval(address spender, uint256 subtractedValue) external returns (bool success) {\\n return decreaseAllowance(spender, subtractedValue);\\n }\\n\\n /// @dev Exists to be backwards compatible with the older naming convention.\\n function increaseApproval(address spender, uint256 addedValue) external {\\n increaseAllowance(spender, addedValue);\\n }\\n\\n /// @notice Check if recipient is valid (not this contract address).\\n /// @param recipient the account we transfer/approve to.\\n /// @dev Reverts with an empty revert to be compatible with the existing link token when\\n /// the recipient is this contract address.\\n modifier validAddress(address recipient) virtual {\\n // solhint-disable-next-line reason-string, custom-errors\\n if (recipient == address(this)) revert();\\n _;\\n }\\n\\n // ================================================================\\n // | Burning & minting |\\n // ================================================================\\n\\n /// @inheritdoc ERC20Burnable\\n /// @dev Uses OZ ERC20 _burn to disallow burning from address(0).\\n /// @dev Decreases the total supply.\\n function burn(uint256 amount) public override(IBurnMintERC20, ERC20Burnable) onlyBurner {\\n super.burn(amount);\\n }\\n\\n /// @inheritdoc IBurnMintERC20\\n /// @dev Alias for BurnFrom for compatibility with the older naming convention.\\n /// @dev Uses burnFrom for all validation & logic.\\n function burn(address account, uint256 amount) public virtual override {\\n burnFrom(account, amount);\\n }\\n\\n /// @inheritdoc ERC20Burnable\\n /// @dev Uses OZ ERC20 _burn to disallow burning from address(0).\\n /// @dev Decreases the total supply.\\n function burnFrom(address account, uint256 amount) public override(IBurnMintERC20, ERC20Burnable) onlyBurner {\\n super.burnFrom(account, amount);\\n }\\n\\n /// @inheritdoc IBurnMintERC20\\n /// @dev Uses OZ ERC20 _mint to disallow minting to address(0).\\n /// @dev Disallows minting to address(this)\\n /// @dev Increases the total supply.\\n function mint(address account, uint256 amount) external override onlyMinter validAddress(account) {\\n if (i_maxSupply != 0 && totalSupply() + amount > i_maxSupply) revert MaxSupplyExceeded(totalSupply() + amount);\\n\\n _mint(account, amount);\\n }\\n\\n // ================================================================\\n // | Roles |\\n // ================================================================\\n\\n /// @notice grants both mint and burn roles to `burnAndMinter`.\\n /// @dev calls public functions so this function does not require\\n /// access controls. This is handled in the inner functions.\\n function grantMintAndBurnRoles(address burnAndMinter) external {\\n grantMintRole(burnAndMinter);\\n grantBurnRole(burnAndMinter);\\n }\\n\\n /// @notice Grants mint role to the given address.\\n /// @dev only the owner can call this function.\\n function grantMintRole(address minter) public onlyOwner {\\n if (s_minters.add(minter)) {\\n emit MintAccessGranted(minter);\\n }\\n }\\n\\n /// @notice Grants burn role to the given address.\\n /// @dev only the owner can call this function.\\n function grantBurnRole(address burner) public onlyOwner {\\n if (s_burners.add(burner)) {\\n emit BurnAccessGranted(burner);\\n }\\n }\\n\\n /// @notice Revokes mint role for the given address.\\n /// @dev only the owner can call this function.\\n function revokeMintRole(address minter) public onlyOwner {\\n if (s_minters.remove(minter)) {\\n emit MintAccessRevoked(minter);\\n }\\n }\\n\\n /// @notice Revokes burn role from the given address.\\n /// @dev only the owner can call this function\\n function revokeBurnRole(address burner) public onlyOwner {\\n if (s_burners.remove(burner)) {\\n emit BurnAccessRevoked(burner);\\n }\\n }\\n\\n /// @notice Returns all permissioned minters\\n function getMinters() public view returns (address[] memory) {\\n return s_minters.values();\\n }\\n\\n /// @notice Returns all permissioned burners\\n function getBurners() public view returns (address[] memory) {\\n return s_burners.values();\\n }\\n\\n // ================================================================\\n // | Access |\\n // ================================================================\\n\\n /// @notice Checks whether a given address is a minter for this token.\\n /// @return true if the address is allowed to mint.\\n function isMinter(address minter) public view returns (bool) {\\n return s_minters.contains(minter);\\n }\\n\\n /// @notice Checks whether a given address is a burner for this token.\\n /// @return true if the address is allowed to burn.\\n function isBurner(address burner) public view returns (bool) {\\n return s_burners.contains(burner);\\n }\\n\\n /// @notice Checks whether the msg.sender is a permissioned minter for this token\\n /// @dev Reverts with a SenderNotMinter if the check fails\\n modifier onlyMinter() {\\n if (!isMinter(msg.sender)) revert SenderNotMinter(msg.sender);\\n _;\\n }\\n\\n /// @notice Checks whether the msg.sender is a permissioned burner for this token\\n /// @dev Reverts with a SenderNotBurner if the check fails\\n modifier onlyBurner() {\\n if (!isBurner(msg.sender)) revert SenderNotBurner(msg.sender);\\n _;\\n }\\n}\\n\",\"keccak256\":\"0xed068708e5c2e87ad74caa7c73a97bc02a106ea5d62698234754f63933abf6b5\",\"license\":\"MIT\"},\"src/interfaces/IBurnMintERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IBurnMintERC20 is IERC20 {\\n /// @notice Mints new tokens for a given address.\\n /// @param account The address to mint the new tokens to.\\n /// @param amount The number of tokens to be minted.\\n /// @dev this function increases the total supply.\\n function mint(address account, uint256 amount) external;\\n\\n /// @notice Burns tokens from the sender.\\n /// @param amount The number of tokens to be burned.\\n /// @dev this function decreases the total supply.\\n function burn(uint256 amount) external;\\n\\n /// @notice Burns tokens from a given address..\\n /// @param account The address to burn tokens from.\\n /// @param amount The number of tokens to be burned.\\n /// @dev this function decreases the total supply.\\n function burn(address account, uint256 amount) external;\\n\\n /// @notice Burns tokens from a given address..\\n /// @param account The address to burn tokens from.\\n /// @param amount The number of tokens to be burned.\\n /// @dev this function decreases the total supply.\\n function burnFrom(address account, uint256 amount) external;\\n}\\n\",\"keccak256\":\"0x8adc632df6a61f0ca93c3be6e25b0334247bfe48fc339ce92b85155766b614bb\",\"license\":\"MIT\"},\"src/interfaces/IERC677.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IERC677 {\\n event Transfer(address indexed from, address indexed to, uint256 value, bytes data);\\n\\n /// @notice Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver\\n /// @param to The address which you want to transfer to\\n /// @param amount The amount of tokens to be transferred\\n /// @param data bytes Additional data with no specified format, sent in call to `to`\\n /// @return true unless throwing\\n function transferAndCall(address to, uint256 amount, bytes memory data) external returns (bool);\\n}\\n\",\"keccak256\":\"0x771321adbdab6bec7d27bcd8a46dfea813f1c97d97a7a671fe35cd87744daee4\",\"license\":\"MIT\"},\"src/interfaces/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.6;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(address sender, uint256 amount, bytes calldata data) external;\\n}\",\"keccak256\":\"0xddc2a487ff19419029168dd870fff6ab8075446948a404276edc7d053e6f9f35\",\"license\":\"MIT\"},\"src/interfaces/IOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IOwnable {\\n function owner() external returns (address);\\n\\n function transferOwnership(address recipient) external;\\n\\n function acceptOwnership() external;\\n}\",\"keccak256\":\"0x15a45e18786bd5f5158260f7b225daf428f76c4d34284d851c4e480f66b13f25\",\"license\":\"MIT\"},\"src/libs/ConfirmedOwner.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ConfirmedOwnerWithProposal.sol\\\";\\n\\n/**\\n * @title The ConfirmedOwner contract\\n * @notice A contract with helpers for basic contract ownership.\\n */\\ncontract ConfirmedOwner is ConfirmedOwnerWithProposal {\\n constructor(address newOwner) ConfirmedOwnerWithProposal(newOwner, address(0)) {}\\n}\",\"keccak256\":\"0x57960637d0ac27af34cde3f0aa709e49f8ae109697695ec73117dfb6d8a4271d\",\"license\":\"MIT\"},\"src/libs/ConfirmedOwnerWithProposal.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"../interfaces/IOwnable.sol\\\";\\n\\n/**\\n * @title The ConfirmedOwner contract\\n * @notice A contract with helpers for basic contract ownership.\\n */\\ncontract ConfirmedOwnerWithProposal is IOwnable {\\n address private s_owner;\\n address private s_pendingOwner;\\n\\n event OwnershipTransferRequested(address indexed from, address indexed to);\\n event OwnershipTransferred(address indexed from, address indexed to);\\n\\n constructor(address newOwner, address pendingOwner) {\\n require(newOwner != address(0), \\\"Cannot set owner to zero\\\");\\n\\n s_owner = newOwner;\\n if (pendingOwner != address(0)) {\\n _transferOwnership(pendingOwner);\\n }\\n }\\n\\n /**\\n * @notice Allows an owner to begin transferring ownership to a new address,\\n * pending.\\n */\\n function transferOwnership(address to) public override onlyOwner {\\n _transferOwnership(to);\\n }\\n\\n /**\\n * @notice Allows an ownership transfer to be completed by the recipient.\\n */\\n function acceptOwnership() external override {\\n require(msg.sender == s_pendingOwner, \\\"Must be proposed owner\\\");\\n\\n address oldOwner = s_owner;\\n s_owner = msg.sender;\\n s_pendingOwner = address(0);\\n\\n emit OwnershipTransferred(oldOwner, msg.sender);\\n }\\n\\n /**\\n * @notice Get the current owner\\n */\\n function owner() public view override returns (address) {\\n return s_owner;\\n }\\n\\n /**\\n * @notice validate, transfer ownership, and emit relevant events\\n */\\n function _transferOwnership(address to) private {\\n require(to != msg.sender, \\\"Cannot transfer to self\\\");\\n\\n s_pendingOwner = to;\\n\\n emit OwnershipTransferRequested(s_owner, to);\\n }\\n\\n /**\\n * @notice validate access\\n */\\n function _validateOwnership() internal view {\\n require(msg.sender == s_owner, \\\"Only callable by owner\\\");\\n }\\n\\n /**\\n * @notice Reverts if called by anyone other than the contract owner.\\n */\\n modifier onlyOwner() {\\n _validateOwnership();\\n _;\\n }\\n}\",\"keccak256\":\"0x1a48a2386fff0c1068a2eed4decbf0f53b3ea8a77a088fa0a9f033a1688b967f\",\"license\":\"MIT\"},\"src/libs/ERC677.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.0;\\n\\nimport {IERC677} from \\\"../interfaces/IERC677.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/IERC677Receiver.sol\\\";\\n\\nimport {ERC20} from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\n\\ncontract ERC677 is IERC677, ERC20 {\\n constructor(string memory name, string memory symbol) ERC20(name, symbol) {}\\n\\n /// @inheritdoc IERC677\\n function transferAndCall(address to, uint256 amount, bytes memory data) public returns (bool success) {\\n super.transfer(to, amount);\\n emit Transfer(msg.sender, to, amount, data);\\n if (to.code.length > 0) {\\n IERC677Receiver(to).onTokenTransfer(msg.sender, amount, data);\\n }\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xe18487d77f4f20750733acff95919cd1f40e8dd32cfd9440e46ef88e4933ffbd\",\"license\":\"UNLICENSED\"},\"src/libs/OwnerIsCreator.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ConfirmedOwner} from \\\"./ConfirmedOwner.sol\\\";\\n\\n/// @title The OwnerIsCreator contract\\n/// @notice A contract with helpers for basic contract ownership.\\ncontract OwnerIsCreator is ConfirmedOwner {\\n constructor() ConfirmedOwner(msg.sender) {}\\n}\\n\",\"keccak256\":\"0x895af02d6a3df2930bbb6ec1f2d68118b492ca6e710ba0c34fcb6b574a0906aa\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60c06040523480156200001157600080fd5b5060405162001c2a38038062001c2a833981016040819052620000349162000277565b338060008686818160036200004a838262000391565b50600462000059828262000391565b5050506001600160a01b0384169150620000bc90505760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600580546001600160a01b0319166001600160a01b0384811691909117909155811615620000ef57620000ef8162000106565b50505060ff90911660805260a052506200045d9050565b336001600160a01b03821603620001605760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000b3565b600680546001600160a01b0319166001600160a01b03838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001da57600080fd5b81516001600160401b0380821115620001f757620001f7620001b2565b604051601f8301601f19908116603f01168101908282118183101715620002225762000222620001b2565b816040528381526020925086838588010111156200023f57600080fd5b600091505b8382101562000263578582018301518183018401529082019062000244565b600093810190920192909252949350505050565b600080600080608085870312156200028e57600080fd5b84516001600160401b0380821115620002a657600080fd5b620002b488838901620001c8565b95506020870151915080821115620002cb57600080fd5b50620002da87828801620001c8565b935050604085015160ff81168114620002f257600080fd5b6060959095015193969295505050565b600181811c908216806200031757607f821691505b6020821081036200033857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200038c57600081815260208120601f850160051c81016020861015620003675750805b601f850160051c820191505b81811015620003885782815560010162000373565b5050505b505050565b81516001600160401b03811115620003ad57620003ad620001b2565b620003c581620003be845462000302565b846200033e565b602080601f831160018114620003fd5760008415620003e45750858301515b600019600386901b1c1916600185901b17855562000388565b600085815260208120601f198616915b828110156200042e578886015182559484019460019091019084016200040d565b50858210156200044d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a051611799620004916000396000818161042d01528181610715015261073f0152600061027101526117996000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c806379cc67901161010f578063c2e3273d116100a2578063d73dd62311610071578063d73dd62314610451578063dd62ed3e14610464578063f2fde38b14610477578063f81094f31461048a57600080fd5b8063c2e3273d146103f2578063c630948d14610405578063c64d0ebc14610418578063d5abeb011461042b57600080fd5b80639dc29fac116100de5780639dc29fac146103a6578063a457c2d7146103b9578063a9059cbb146103cc578063aa271e1a146103df57600080fd5b806379cc67901461036857806386fe8b431461037b5780638da5cb5b1461038357806395d89b411461039e57600080fd5b806340c10f19116101875780636618846311610156578063661884631461030f5780636b32810b1461032257806370a082311461033757806379ba50971461036057600080fd5b806340c10f19146102c157806342966c68146102d65780634334614a146102e95780634f5632f8146102fc57600080fd5b806323b872dd116101c357806323b872dd14610257578063313ce5671461026a578063395093511461029b5780634000aea0146102ae57600080fd5b806301ffc9a7146101f557806306fdde031461021d578063095ea7b31461023257806318160ddd14610245575b600080fd5b6102086102033660046113d6565b61049d565b60405190151581526020015b60405180910390f35b61022561050a565b6040516102149190611446565b610208610240366004611475565b61059c565b6002545b604051908152602001610214565b61020861026536600461149f565b6105b4565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610214565b6102086102a9366004611475565b6105d8565b6102086102bc3660046114f1565b6105fa565b6102d46102cf366004611475565b6106d0565b005b6102d46102e43660046115bc565b6107b8565b6102086102f73660046115d5565b6107ec565b6102d461030a3660046115d5565b6107f9565b61020861031d366004611475565b610848565b61032a61085b565b60405161021491906115f0565b6102496103453660046115d5565b6001600160a01b031660009081526020819052604090205490565b6102d461086c565b6102d4610376366004611475565b61091a565b61032a610950565b6005546040516001600160a01b039091168152602001610214565b61022561095c565b6102d46103b4366004611475565b61096b565b6102086103c7366004611475565b610975565b6102086103da366004611475565b6109f0565b6102086103ed3660046115d5565b6109fe565b6102d46104003660046115d5565b610a0b565b6102d46104133660046115d5565b610a5a565b6102d46104263660046115d5565b610a68565b7f0000000000000000000000000000000000000000000000000000000000000000610249565b6102d461045f366004611475565b610ab7565b61024961047236600461163d565b610ac1565b6102d46104853660046115d5565b610aec565b6102d46104983660046115d5565b610afd565b60006001600160e01b031982166336372b0760e01b14806104ce57506001600160e01b03198216630200057560e51b145b806104e957506001600160e01b0319821663e6599b4d60e01b145b8061050457506001600160e01b031982166301ffc9a760e01b145b92915050565b60606003805461051990611670565b80601f016020809104026020016040519081016040528092919081815260200182805461054590611670565b80156105925780601f1061056757610100808354040283529160200191610592565b820191906000526020600020905b81548152906001019060200180831161057557829003601f168201915b5050505050905090565b6000336105aa818585610b4c565b5060019392505050565b6000336105c2858285610b73565b6105cd858585610be7565b506001949350505050565b6000336105aa8185856105eb8383610ac1565b6105f591906116c0565b610b4c565b600061060684846109f0565b50836001600160a01b0316336001600160a01b03167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16858560405161064c9291906116d3565b60405180910390a36001600160a01b0384163b156105aa57604051635260769b60e11b81526001600160a01b0385169063a4c0ed3690610694903390879087906004016116f4565b600060405180830381600087803b1580156106ae57600080fd5b505af11580156106c2573d6000803e3d6000fd5b505050505060019392505050565b6106d9336109fe565b6106fd5760405163e2c8c9d560e01b81523360048201526024015b60405180910390fd5b81306001600160a01b0382160361071357600080fd5b7f00000000000000000000000000000000000000000000000000000000000000001580159061077457507f00000000000000000000000000000000000000000000000000000000000000008261076860025490565b61077291906116c0565b115b156107a9578161078360025490565b61078d91906116c0565b60405163cbbf111360e01b81526004016106f491815260200190565b6107b38383610c08565b505050565b6107c1336107ec565b6107e05760405163c820b10b60e01b81523360048201526024016106f4565b6107e981610cc7565b50565b6000610504600983610cd1565b610801610cf3565b61080c600982610d48565b156107e9576040516001600160a01b038216907f0a675452746933cefe3d74182e78db7afe57ba60eaa4234b5d85e9aa41b0610c90600090a250565b60006108548383610975565b9392505050565b60606108676007610d5d565b905090565b6006546001600160a01b031633146108bf5760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b60448201526064016106f4565b600580546001600160a01b0319808216339081179093556006805490911690556040516001600160a01b03909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b610923336107ec565b6109425760405163c820b10b60e01b81523360048201526024016106f4565b61094c8282610d6a565b5050565b60606108676009610d5d565b60606004805461051990611670565b61094c828261091a565b600033816109838286610ac1565b9050838110156109e35760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016106f4565b6105cd8286868403610b4c565b6000336105aa818585610be7565b6000610504600783610cd1565b610a13610cf3565b610a1e600782610d7f565b156107e9576040516001600160a01b038216907fe46fef8bbff1389d9010703cf8ebb363fb3daf5bf56edc27080b67bc8d9251ea90600090a250565b610a6381610a0b565b6107e9815b610a70610cf3565b610a7b600982610d7f565b156107e9576040516001600160a01b038216907f92308bb7573b2a3d17ddb868b39d8ebec433f3194421abc22d084f89658c9bad90600090a250565b6107b382826105d8565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610af4610cf3565b6107e981610d94565b610b05610cf3565b610b10600782610d48565b156107e9576040516001600160a01b038216907fed998b960f6340d045f620c119730f7aa7995e7425c2401d3a5b64ff998a59e990600090a250565b81306001600160a01b03821603610b6257600080fd5b610b6d848484610e3e565b50505050565b6000610b7f8484610ac1565b90506000198114610b6d5781811015610bda5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106f4565b610b6d8484848403610b4c565b81306001600160a01b03821603610bfd57600080fd5b610b6d848484610f62565b6001600160a01b038216610c5e5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106f4565b8060026000828254610c7091906116c0565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6107e93382611106565b6001600160a01b03811660009081526001830160205260408120541515610854565b6005546001600160a01b03163314610d465760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b60448201526064016106f4565b565b6000610854836001600160a01b038416611238565b606060006108548361132b565b610d75823383610b73565b61094c8282611106565b6000610854836001600160a01b038416611387565b336001600160a01b03821603610dec5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106f4565b600680546001600160a01b0319166001600160a01b03838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b6001600160a01b038316610ea05760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016106f4565b6001600160a01b038216610f015760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016106f4565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b038316610fc65760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016106f4565b6001600160a01b0382166110285760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016106f4565b6001600160a01b038316600090815260208190526040902054818110156110a05760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016106f4565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610b6d565b6001600160a01b0382166111665760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016106f4565b6001600160a01b038216600090815260208190526040902054818110156111da5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016106f4565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6000818152600183016020526040812054801561132157600061125c600183611724565b855490915060009061127090600190611724565b90508181146112d557600086600001828154811061129057611290611737565b90600052602060002001549050808760000184815481106112b3576112b3611737565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806112e6576112e661174d565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610504565b6000915050610504565b60608160000180548060200260200160405190810160405280929190818152602001828054801561137b57602002820191906000526020600020905b815481526020019060010190808311611367575b50505050509050919050565b60008181526001830160205260408120546113ce57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610504565b506000610504565b6000602082840312156113e857600080fd5b81356001600160e01b03198116811461085457600080fd5b6000815180845260005b818110156114265760208185018101518683018201520161140a565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006108546020830184611400565b80356001600160a01b038116811461147057600080fd5b919050565b6000806040838503121561148857600080fd5b61149183611459565b946020939093013593505050565b6000806000606084860312156114b457600080fd5b6114bd84611459565b92506114cb60208501611459565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b60008060006060848603121561150657600080fd5b61150f84611459565b925060208401359150604084013567ffffffffffffffff8082111561153357600080fd5b818601915086601f83011261154757600080fd5b813581811115611559576115596114db565b604051601f8201601f19908116603f01168101908382118183101715611581576115816114db565b8160405282815289602084870101111561159a57600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b6000602082840312156115ce57600080fd5b5035919050565b6000602082840312156115e757600080fd5b61085482611459565b6020808252825182820181905260009190848201906040850190845b818110156116315783516001600160a01b03168352928401929184019160010161160c565b50909695505050505050565b6000806040838503121561165057600080fd5b61165983611459565b915061166760208401611459565b90509250929050565b600181811c9082168061168457607f821691505b6020821081036116a457634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610504576105046116aa565b8281526040602082015260006116ec6040830184611400565b949350505050565b60018060a01b038416815282602082015260606040820152600061171b6060830184611400565b95945050505050565b81810381811115610504576105046116aa565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fdfea264697066735822122026bf827ff7c4546d08bc173f7cb82c7ccf3be629370907c1d7e2e74f372b4c0164736f6c63430008140033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101f05760003560e01c806379cc67901161010f578063c2e3273d116100a2578063d73dd62311610071578063d73dd62314610451578063dd62ed3e14610464578063f2fde38b14610477578063f81094f31461048a57600080fd5b8063c2e3273d146103f2578063c630948d14610405578063c64d0ebc14610418578063d5abeb011461042b57600080fd5b80639dc29fac116100de5780639dc29fac146103a6578063a457c2d7146103b9578063a9059cbb146103cc578063aa271e1a146103df57600080fd5b806379cc67901461036857806386fe8b431461037b5780638da5cb5b1461038357806395d89b411461039e57600080fd5b806340c10f19116101875780636618846311610156578063661884631461030f5780636b32810b1461032257806370a082311461033757806379ba50971461036057600080fd5b806340c10f19146102c157806342966c68146102d65780634334614a146102e95780634f5632f8146102fc57600080fd5b806323b872dd116101c357806323b872dd14610257578063313ce5671461026a578063395093511461029b5780634000aea0146102ae57600080fd5b806301ffc9a7146101f557806306fdde031461021d578063095ea7b31461023257806318160ddd14610245575b600080fd5b6102086102033660046113d6565b61049d565b60405190151581526020015b60405180910390f35b61022561050a565b6040516102149190611446565b610208610240366004611475565b61059c565b6002545b604051908152602001610214565b61020861026536600461149f565b6105b4565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610214565b6102086102a9366004611475565b6105d8565b6102086102bc3660046114f1565b6105fa565b6102d46102cf366004611475565b6106d0565b005b6102d46102e43660046115bc565b6107b8565b6102086102f73660046115d5565b6107ec565b6102d461030a3660046115d5565b6107f9565b61020861031d366004611475565b610848565b61032a61085b565b60405161021491906115f0565b6102496103453660046115d5565b6001600160a01b031660009081526020819052604090205490565b6102d461086c565b6102d4610376366004611475565b61091a565b61032a610950565b6005546040516001600160a01b039091168152602001610214565b61022561095c565b6102d46103b4366004611475565b61096b565b6102086103c7366004611475565b610975565b6102086103da366004611475565b6109f0565b6102086103ed3660046115d5565b6109fe565b6102d46104003660046115d5565b610a0b565b6102d46104133660046115d5565b610a5a565b6102d46104263660046115d5565b610a68565b7f0000000000000000000000000000000000000000000000000000000000000000610249565b6102d461045f366004611475565b610ab7565b61024961047236600461163d565b610ac1565b6102d46104853660046115d5565b610aec565b6102d46104983660046115d5565b610afd565b60006001600160e01b031982166336372b0760e01b14806104ce57506001600160e01b03198216630200057560e51b145b806104e957506001600160e01b0319821663e6599b4d60e01b145b8061050457506001600160e01b031982166301ffc9a760e01b145b92915050565b60606003805461051990611670565b80601f016020809104026020016040519081016040528092919081815260200182805461054590611670565b80156105925780601f1061056757610100808354040283529160200191610592565b820191906000526020600020905b81548152906001019060200180831161057557829003601f168201915b5050505050905090565b6000336105aa818585610b4c565b5060019392505050565b6000336105c2858285610b73565b6105cd858585610be7565b506001949350505050565b6000336105aa8185856105eb8383610ac1565b6105f591906116c0565b610b4c565b600061060684846109f0565b50836001600160a01b0316336001600160a01b03167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16858560405161064c9291906116d3565b60405180910390a36001600160a01b0384163b156105aa57604051635260769b60e11b81526001600160a01b0385169063a4c0ed3690610694903390879087906004016116f4565b600060405180830381600087803b1580156106ae57600080fd5b505af11580156106c2573d6000803e3d6000fd5b505050505060019392505050565b6106d9336109fe565b6106fd5760405163e2c8c9d560e01b81523360048201526024015b60405180910390fd5b81306001600160a01b0382160361071357600080fd5b7f00000000000000000000000000000000000000000000000000000000000000001580159061077457507f00000000000000000000000000000000000000000000000000000000000000008261076860025490565b61077291906116c0565b115b156107a9578161078360025490565b61078d91906116c0565b60405163cbbf111360e01b81526004016106f491815260200190565b6107b38383610c08565b505050565b6107c1336107ec565b6107e05760405163c820b10b60e01b81523360048201526024016106f4565b6107e981610cc7565b50565b6000610504600983610cd1565b610801610cf3565b61080c600982610d48565b156107e9576040516001600160a01b038216907f0a675452746933cefe3d74182e78db7afe57ba60eaa4234b5d85e9aa41b0610c90600090a250565b60006108548383610975565b9392505050565b60606108676007610d5d565b905090565b6006546001600160a01b031633146108bf5760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b60448201526064016106f4565b600580546001600160a01b0319808216339081179093556006805490911690556040516001600160a01b03909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b610923336107ec565b6109425760405163c820b10b60e01b81523360048201526024016106f4565b61094c8282610d6a565b5050565b60606108676009610d5d565b60606004805461051990611670565b61094c828261091a565b600033816109838286610ac1565b9050838110156109e35760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016106f4565b6105cd8286868403610b4c565b6000336105aa818585610be7565b6000610504600783610cd1565b610a13610cf3565b610a1e600782610d7f565b156107e9576040516001600160a01b038216907fe46fef8bbff1389d9010703cf8ebb363fb3daf5bf56edc27080b67bc8d9251ea90600090a250565b610a6381610a0b565b6107e9815b610a70610cf3565b610a7b600982610d7f565b156107e9576040516001600160a01b038216907f92308bb7573b2a3d17ddb868b39d8ebec433f3194421abc22d084f89658c9bad90600090a250565b6107b382826105d8565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610af4610cf3565b6107e981610d94565b610b05610cf3565b610b10600782610d48565b156107e9576040516001600160a01b038216907fed998b960f6340d045f620c119730f7aa7995e7425c2401d3a5b64ff998a59e990600090a250565b81306001600160a01b03821603610b6257600080fd5b610b6d848484610e3e565b50505050565b6000610b7f8484610ac1565b90506000198114610b6d5781811015610bda5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106f4565b610b6d8484848403610b4c565b81306001600160a01b03821603610bfd57600080fd5b610b6d848484610f62565b6001600160a01b038216610c5e5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106f4565b8060026000828254610c7091906116c0565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6107e93382611106565b6001600160a01b03811660009081526001830160205260408120541515610854565b6005546001600160a01b03163314610d465760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b60448201526064016106f4565b565b6000610854836001600160a01b038416611238565b606060006108548361132b565b610d75823383610b73565b61094c8282611106565b6000610854836001600160a01b038416611387565b336001600160a01b03821603610dec5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106f4565b600680546001600160a01b0319166001600160a01b03838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b6001600160a01b038316610ea05760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016106f4565b6001600160a01b038216610f015760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016106f4565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b038316610fc65760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016106f4565b6001600160a01b0382166110285760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016106f4565b6001600160a01b038316600090815260208190526040902054818110156110a05760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016106f4565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610b6d565b6001600160a01b0382166111665760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016106f4565b6001600160a01b038216600090815260208190526040902054818110156111da5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016106f4565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6000818152600183016020526040812054801561132157600061125c600183611724565b855490915060009061127090600190611724565b90508181146112d557600086600001828154811061129057611290611737565b90600052602060002001549050808760000184815481106112b3576112b3611737565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806112e6576112e661174d565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610504565b6000915050610504565b60608160000180548060200260200160405190810160405280929190818152602001828054801561137b57602002820191906000526020600020905b815481526020019060010190808311611367575b50505050509050919050565b60008181526001830160205260408120546113ce57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610504565b506000610504565b6000602082840312156113e857600080fd5b81356001600160e01b03198116811461085457600080fd5b6000815180845260005b818110156114265760208185018101518683018201520161140a565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006108546020830184611400565b80356001600160a01b038116811461147057600080fd5b919050565b6000806040838503121561148857600080fd5b61149183611459565b946020939093013593505050565b6000806000606084860312156114b457600080fd5b6114bd84611459565b92506114cb60208501611459565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b60008060006060848603121561150657600080fd5b61150f84611459565b925060208401359150604084013567ffffffffffffffff8082111561153357600080fd5b818601915086601f83011261154757600080fd5b813581811115611559576115596114db565b604051601f8201601f19908116603f01168101908382118183101715611581576115816114db565b8160405282815289602084870101111561159a57600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b6000602082840312156115ce57600080fd5b5035919050565b6000602082840312156115e757600080fd5b61085482611459565b6020808252825182820181905260009190848201906040850190845b818110156116315783516001600160a01b03168352928401929184019160010161160c565b50909695505050505050565b6000806040838503121561165057600080fd5b61165983611459565b915061166760208401611459565b90509250929050565b600181811c9082168061168457607f821691505b6020821081036116a457634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610504576105046116aa565b8281526040602082015260006116ec6040830184611400565b949350505050565b60018060a01b038416815282602082015260606040820152600061171b6060830184611400565b95945050505050565b81810381811115610504576105046116aa565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fdfea264697066735822122026bf827ff7c4546d08bc173f7cb82c7ccf3be629370907c1d7e2e74f372b4c0164736f6c63430008140033", + "devdoc": { + "details": "The total supply can be limited during deployment.", + "events": { + "Approval(address,address,uint256)": { + "details": "Emitted when the allowance of a `spender` for an `owner` is set by a call to {approve}. `value` is the new allowance." + }, + "Transfer(address,address,uint256)": { + "details": "Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero." + } + }, + "kind": "dev", + "methods": { + "allowance(address,address)": { + "details": "See {IERC20-allowance}." + }, + "approve(address,uint256)": { + "details": "See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address." + }, + "balanceOf(address)": { + "details": "See {IERC20-balanceOf}." + }, + "burn(address,uint256)": { + "details": "Alias for BurnFrom for compatibility with the older naming convention.Uses burnFrom for all validation & logic.", + "params": { + "account": "The address to burn tokens from.", + "amount": "The number of tokens to be burned." + } + }, + "burn(uint256)": { + "details": "Uses OZ ERC20 _burn to disallow burning from address(0).Decreases the total supply." + }, + "burnFrom(address,uint256)": { + "details": "Uses OZ ERC20 _burn to disallow burning from address(0).Decreases the total supply." + }, + "decimals()": { + "details": "Returns the number of decimals used in its user representation." + }, + "decreaseAllowance(address,uint256)": { + "details": "Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`." + }, + "decreaseApproval(address,uint256)": { + "details": "Exists to be backwards compatible with the older naming convention." + }, + "grantBurnRole(address)": { + "details": "only the owner can call this function." + }, + "grantMintAndBurnRoles(address)": { + "details": "calls public functions so this function does not require access controls. This is handled in the inner functions." + }, + "grantMintRole(address)": { + "details": "only the owner can call this function." + }, + "increaseAllowance(address,uint256)": { + "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." + }, + "increaseApproval(address,uint256)": { + "details": "Exists to be backwards compatible with the older naming convention." + }, + "isBurner(address)": { + "returns": { + "_0": "true if the address is allowed to burn." + } + }, + "isMinter(address)": { + "returns": { + "_0": "true if the address is allowed to mint." + } + }, + "maxSupply()": { + "details": "Returns the max supply of the token, 0 if unlimited." + }, + "mint(address,uint256)": { + "details": "Uses OZ ERC20 _mint to disallow minting to address(0).Disallows minting to address(this)Increases the total supply.", + "params": { + "account": "The address to mint the new tokens to.", + "amount": "The number of tokens to be minted." + } + }, + "name()": { + "details": "Returns the name of the token." + }, + "revokeBurnRole(address)": { + "details": "only the owner can call this function" + }, + "revokeMintRole(address)": { + "details": "only the owner can call this function." + }, + "supportsInterface(bytes4)": { + "details": "Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas." + }, + "symbol()": { + "details": "Returns the symbol of the token, usually a shorter version of the name." + }, + "totalSupply()": { + "details": "See {IERC20-totalSupply}." + }, + "transfer(address,uint256)": { + "details": "See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`." + }, + "transferAndCall(address,uint256,bytes)": { + "params": { + "amount": "The amount of tokens to be transferred", + "data": "bytes Additional data with no specified format, sent in call to `to`", + "to": "The address which you want to transfer to" + }, + "returns": { + "success": "true unless throwing" + } + }, + "transferFrom(address,address,uint256)": { + "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`." + } + }, + "stateVariables": { + "i_decimals": { + "details": "The number of decimals for the token" + }, + "i_maxSupply": { + "details": "The maximum supply of the token, 0 if unlimited" + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "acceptOwnership()": { + "notice": "Allows an ownership transfer to be completed by the recipient." + }, + "burn(address,uint256)": { + "notice": "Burns tokens from a given address.." + }, + "getBurners()": { + "notice": "Returns all permissioned burners" + }, + "getMinters()": { + "notice": "Returns all permissioned minters" + }, + "grantBurnRole(address)": { + "notice": "Grants burn role to the given address." + }, + "grantMintAndBurnRoles(address)": { + "notice": "grants both mint and burn roles to `burnAndMinter`." + }, + "grantMintRole(address)": { + "notice": "Grants mint role to the given address." + }, + "isBurner(address)": { + "notice": "Checks whether a given address is a burner for this token." + }, + "isMinter(address)": { + "notice": "Checks whether a given address is a minter for this token." + }, + "mint(address,uint256)": { + "notice": "Mints new tokens for a given address." + }, + "owner()": { + "notice": "Get the current owner" + }, + "revokeBurnRole(address)": { + "notice": "Revokes burn role from the given address." + }, + "revokeMintRole(address)": { + "notice": "Revokes mint role for the given address." + }, + "transferAndCall(address,uint256,bytes)": { + "notice": "Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver" + }, + "transferOwnership(address)": { + "notice": "Allows an owner to begin transferring ownership to a new address, pending." + } + }, + "notice": "A basic ERC677 compatible token contract with burn and minting roles.", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 15, + "contract": "src/LDY.sol:LDY", + "label": "_balances", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 21, + "contract": "src/LDY.sol:LDY", + "label": "_allowances", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 23, + "contract": "src/LDY.sol:LDY", + "label": "_totalSupply", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 25, + "contract": "src/LDY.sol:LDY", + "label": "_name", + "offset": 0, + "slot": "3", + "type": "t_string_storage" + }, + { + "astId": 27, + "contract": "src/LDY.sol:LDY", + "label": "_symbol", + "offset": 0, + "slot": "4", + "type": "t_string_storage" + }, + { + "astId": 2012, + "contract": "src/LDY.sol:LDY", + "label": "s_owner", + "offset": 0, + "slot": "5", + "type": "t_address" + }, + { + "astId": 2014, + "contract": "src/LDY.sol:LDY", + "label": "s_pendingOwner", + "offset": 0, + "slot": "6", + "type": "t_address" + }, + { + "astId": 1444, + "contract": "src/LDY.sol:LDY", + "label": "s_minters", + "offset": 0, + "slot": "7", + "type": "t_struct(AddressSet)1093_storage" + }, + { + "astId": 1447, + "contract": "src/LDY.sol:LDY", + "label": "s_burners", + "offset": 0, + "slot": "9", + "type": "t_struct(AddressSet)1093_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "base": "t_bytes32", + "encoding": "dynamic_array", + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(AddressSet)1093_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.AddressSet", + "members": [ + { + "astId": 1092, + "contract": "src/LDY.sol:LDY", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)778_storage" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Set)778_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 773, + "contract": "src/LDY.sol:LDY", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 777, + "contract": "src/LDY.sol:LDY", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/hardhat/deployments/base/solcInputs/d8b5802e009f6fee7aed14d8582e28a9.json b/hardhat/deployments/base/solcInputs/d8b5802e009f6fee7aed14d8582e28a9.json new file mode 100644 index 0000000..b77ec66 --- /dev/null +++ b/hardhat/deployments/base/solcInputs/d8b5802e009f6fee7aed14d8582e28a9.json @@ -0,0 +1,81 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../../../utils/Context.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20Burnable is Context, ERC20 {\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "src/interfaces/IBurnMintERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface IBurnMintERC20 is IERC20 {\n /// @notice Mints new tokens for a given address.\n /// @param account The address to mint the new tokens to.\n /// @param amount The number of tokens to be minted.\n /// @dev this function increases the total supply.\n function mint(address account, uint256 amount) external;\n\n /// @notice Burns tokens from the sender.\n /// @param amount The number of tokens to be burned.\n /// @dev this function decreases the total supply.\n function burn(uint256 amount) external;\n\n /// @notice Burns tokens from a given address..\n /// @param account The address to burn tokens from.\n /// @param amount The number of tokens to be burned.\n /// @dev this function decreases the total supply.\n function burn(address account, uint256 amount) external;\n\n /// @notice Burns tokens from a given address..\n /// @param account The address to burn tokens from.\n /// @param amount The number of tokens to be burned.\n /// @dev this function decreases the total supply.\n function burnFrom(address account, uint256 amount) external;\n}\n" + }, + "src/interfaces/IERC677.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IERC677 {\n event Transfer(address indexed from, address indexed to, uint256 value, bytes data);\n\n /// @notice Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver\n /// @param to The address which you want to transfer to\n /// @param amount The amount of tokens to be transferred\n /// @param data bytes Additional data with no specified format, sent in call to `to`\n /// @return true unless throwing\n function transferAndCall(address to, uint256 amount, bytes memory data) external returns (bool);\n}\n" + }, + "src/interfaces/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.6;\n\ninterface IERC677Receiver {\n function onTokenTransfer(address sender, uint256 amount, bytes calldata data) external;\n}" + }, + "src/interfaces/IOwnable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IOwnable {\n function owner() external returns (address);\n\n function transferOwnership(address recipient) external;\n\n function acceptOwnership() external;\n}" + }, + "src/LDY.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IBurnMintERC20} from \"./interfaces/IBurnMintERC20.sol\";\nimport {IERC677} from \"./interfaces/IERC677.sol\";\n\nimport {ERC677} from \"./libs/ERC677.sol\";\nimport {OwnerIsCreator} from \"./libs/OwnerIsCreator.sol\";\n\nimport {ERC20Burnable} from \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/**\n * @title LDY\n * @dev The $LDY is the utility and governance token of the entire Ledgity ecosystem.\n *\n * This contract is taken from the official Chainlink CCIP cross-chain token template:\n * https://github.com/smartcontractkit/ccip/blob/onchain-release/v1.1.0/contracts/src/v0.8/shared/token/ERC677/BurnMintERC677.sol\n * \n * No changes have been made to the original contract; only the imports and folder\n * structure have been reworked. This was done to eliminate hundreds of unused files\n * and to import OpenZeppelin libraries directly from their NPM package.\n *\n * $LDY token is non-upgradeable, non-pausable, and non-restrictable.\n *\n * Specs:\n * - Name: Ledgity Token\n * - Symbol: LDY\n * - Decimals: 18\n * - Total supply: 75,000,000\n *\n * @custom:security-contact security@ledgity.com\n */\n\n/// @notice A basic ERC677 compatible token contract with burn and minting roles.\n/// @dev The total supply can be limited during deployment.\ncontract LDY is IBurnMintERC20, ERC677, IERC165, ERC20Burnable, OwnerIsCreator {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n error SenderNotMinter(address sender);\n error SenderNotBurner(address sender);\n error MaxSupplyExceeded(uint256 supplyAfterMint);\n\n event MintAccessGranted(address indexed minter);\n event BurnAccessGranted(address indexed burner);\n event MintAccessRevoked(address indexed minter);\n event BurnAccessRevoked(address indexed burner);\n\n // @dev the allowed minter addresses\n EnumerableSet.AddressSet internal s_minters;\n // @dev the allowed burner addresses\n EnumerableSet.AddressSet internal s_burners;\n\n /// @dev The number of decimals for the token\n uint8 internal immutable i_decimals;\n\n /// @dev The maximum supply of the token, 0 if unlimited\n uint256 internal immutable i_maxSupply;\n\n constructor(string memory name, string memory symbol, uint8 decimals_, uint256 maxSupply_) ERC677(name, symbol) {\n i_decimals = decimals_;\n i_maxSupply = maxSupply_;\n }\n\n function supportsInterface(bytes4 interfaceId) public pure virtual override returns (bool) {\n return\n interfaceId == type(IERC20).interfaceId ||\n interfaceId == type(IERC677).interfaceId ||\n interfaceId == type(IBurnMintERC20).interfaceId ||\n interfaceId == type(IERC165).interfaceId;\n }\n\n // ================================================================\n // | ERC20 |\n // ================================================================\n\n /// @dev Returns the number of decimals used in its user representation.\n function decimals() public view virtual override returns (uint8) {\n return i_decimals;\n }\n\n /// @dev Returns the max supply of the token, 0 if unlimited.\n function maxSupply() public view virtual returns (uint256) {\n return i_maxSupply;\n }\n\n /// @dev Uses OZ ERC20 _transfer to disallow sending to address(0).\n /// @dev Disallows sending to address(this)\n function _transfer(address from, address to, uint256 amount) internal virtual override validAddress(to) {\n super._transfer(from, to, amount);\n }\n\n /// @dev Uses OZ ERC20 _approve to disallow approving for address(0).\n /// @dev Disallows approving for address(this)\n function _approve(address owner, address spender, uint256 amount) internal virtual override validAddress(spender) {\n super._approve(owner, spender, amount);\n }\n\n /// @dev Exists to be backwards compatible with the older naming convention.\n function decreaseApproval(address spender, uint256 subtractedValue) external returns (bool success) {\n return decreaseAllowance(spender, subtractedValue);\n }\n\n /// @dev Exists to be backwards compatible with the older naming convention.\n function increaseApproval(address spender, uint256 addedValue) external {\n increaseAllowance(spender, addedValue);\n }\n\n /// @notice Check if recipient is valid (not this contract address).\n /// @param recipient the account we transfer/approve to.\n /// @dev Reverts with an empty revert to be compatible with the existing link token when\n /// the recipient is this contract address.\n modifier validAddress(address recipient) virtual {\n // solhint-disable-next-line reason-string, custom-errors\n if (recipient == address(this)) revert();\n _;\n }\n\n // ================================================================\n // | Burning & minting |\n // ================================================================\n\n /// @inheritdoc ERC20Burnable\n /// @dev Uses OZ ERC20 _burn to disallow burning from address(0).\n /// @dev Decreases the total supply.\n function burn(uint256 amount) public override(IBurnMintERC20, ERC20Burnable) onlyBurner {\n super.burn(amount);\n }\n\n /// @inheritdoc IBurnMintERC20\n /// @dev Alias for BurnFrom for compatibility with the older naming convention.\n /// @dev Uses burnFrom for all validation & logic.\n function burn(address account, uint256 amount) public virtual override {\n burnFrom(account, amount);\n }\n\n /// @inheritdoc ERC20Burnable\n /// @dev Uses OZ ERC20 _burn to disallow burning from address(0).\n /// @dev Decreases the total supply.\n function burnFrom(address account, uint256 amount) public override(IBurnMintERC20, ERC20Burnable) onlyBurner {\n super.burnFrom(account, amount);\n }\n\n /// @inheritdoc IBurnMintERC20\n /// @dev Uses OZ ERC20 _mint to disallow minting to address(0).\n /// @dev Disallows minting to address(this)\n /// @dev Increases the total supply.\n function mint(address account, uint256 amount) external override onlyMinter validAddress(account) {\n if (i_maxSupply != 0 && totalSupply() + amount > i_maxSupply) revert MaxSupplyExceeded(totalSupply() + amount);\n\n _mint(account, amount);\n }\n\n // ================================================================\n // | Roles |\n // ================================================================\n\n /// @notice grants both mint and burn roles to `burnAndMinter`.\n /// @dev calls public functions so this function does not require\n /// access controls. This is handled in the inner functions.\n function grantMintAndBurnRoles(address burnAndMinter) external {\n grantMintRole(burnAndMinter);\n grantBurnRole(burnAndMinter);\n }\n\n /// @notice Grants mint role to the given address.\n /// @dev only the owner can call this function.\n function grantMintRole(address minter) public onlyOwner {\n if (s_minters.add(minter)) {\n emit MintAccessGranted(minter);\n }\n }\n\n /// @notice Grants burn role to the given address.\n /// @dev only the owner can call this function.\n function grantBurnRole(address burner) public onlyOwner {\n if (s_burners.add(burner)) {\n emit BurnAccessGranted(burner);\n }\n }\n\n /// @notice Revokes mint role for the given address.\n /// @dev only the owner can call this function.\n function revokeMintRole(address minter) public onlyOwner {\n if (s_minters.remove(minter)) {\n emit MintAccessRevoked(minter);\n }\n }\n\n /// @notice Revokes burn role from the given address.\n /// @dev only the owner can call this function\n function revokeBurnRole(address burner) public onlyOwner {\n if (s_burners.remove(burner)) {\n emit BurnAccessRevoked(burner);\n }\n }\n\n /// @notice Returns all permissioned minters\n function getMinters() public view returns (address[] memory) {\n return s_minters.values();\n }\n\n /// @notice Returns all permissioned burners\n function getBurners() public view returns (address[] memory) {\n return s_burners.values();\n }\n\n // ================================================================\n // | Access |\n // ================================================================\n\n /// @notice Checks whether a given address is a minter for this token.\n /// @return true if the address is allowed to mint.\n function isMinter(address minter) public view returns (bool) {\n return s_minters.contains(minter);\n }\n\n /// @notice Checks whether a given address is a burner for this token.\n /// @return true if the address is allowed to burn.\n function isBurner(address burner) public view returns (bool) {\n return s_burners.contains(burner);\n }\n\n /// @notice Checks whether the msg.sender is a permissioned minter for this token\n /// @dev Reverts with a SenderNotMinter if the check fails\n modifier onlyMinter() {\n if (!isMinter(msg.sender)) revert SenderNotMinter(msg.sender);\n _;\n }\n\n /// @notice Checks whether the msg.sender is a permissioned burner for this token\n /// @dev Reverts with a SenderNotBurner if the check fails\n modifier onlyBurner() {\n if (!isBurner(msg.sender)) revert SenderNotBurner(msg.sender);\n _;\n }\n}\n" + }, + "src/libs/ConfirmedOwner.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./ConfirmedOwnerWithProposal.sol\";\n\n/**\n * @title The ConfirmedOwner contract\n * @notice A contract with helpers for basic contract ownership.\n */\ncontract ConfirmedOwner is ConfirmedOwnerWithProposal {\n constructor(address newOwner) ConfirmedOwnerWithProposal(newOwner, address(0)) {}\n}" + }, + "src/libs/ConfirmedOwnerWithProposal.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"../interfaces/IOwnable.sol\";\n\n/**\n * @title The ConfirmedOwner contract\n * @notice A contract with helpers for basic contract ownership.\n */\ncontract ConfirmedOwnerWithProposal is IOwnable {\n address private s_owner;\n address private s_pendingOwner;\n\n event OwnershipTransferRequested(address indexed from, address indexed to);\n event OwnershipTransferred(address indexed from, address indexed to);\n\n constructor(address newOwner, address pendingOwner) {\n require(newOwner != address(0), \"Cannot set owner to zero\");\n\n s_owner = newOwner;\n if (pendingOwner != address(0)) {\n _transferOwnership(pendingOwner);\n }\n }\n\n /**\n * @notice Allows an owner to begin transferring ownership to a new address,\n * pending.\n */\n function transferOwnership(address to) public override onlyOwner {\n _transferOwnership(to);\n }\n\n /**\n * @notice Allows an ownership transfer to be completed by the recipient.\n */\n function acceptOwnership() external override {\n require(msg.sender == s_pendingOwner, \"Must be proposed owner\");\n\n address oldOwner = s_owner;\n s_owner = msg.sender;\n s_pendingOwner = address(0);\n\n emit OwnershipTransferred(oldOwner, msg.sender);\n }\n\n /**\n * @notice Get the current owner\n */\n function owner() public view override returns (address) {\n return s_owner;\n }\n\n /**\n * @notice validate, transfer ownership, and emit relevant events\n */\n function _transferOwnership(address to) private {\n require(to != msg.sender, \"Cannot transfer to self\");\n\n s_pendingOwner = to;\n\n emit OwnershipTransferRequested(s_owner, to);\n }\n\n /**\n * @notice validate access\n */\n function _validateOwnership() internal view {\n require(msg.sender == s_owner, \"Only callable by owner\");\n }\n\n /**\n * @notice Reverts if called by anyone other than the contract owner.\n */\n modifier onlyOwner() {\n _validateOwnership();\n _;\n }\n}" + }, + "src/libs/ERC677.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IERC677} from \"../interfaces/IERC677.sol\";\nimport {IERC677Receiver} from \"../interfaces/IERC677Receiver.sol\";\n\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract ERC677 is IERC677, ERC20 {\n constructor(string memory name, string memory symbol) ERC20(name, symbol) {}\n\n /// @inheritdoc IERC677\n function transferAndCall(address to, uint256 amount, bytes memory data) public returns (bool success) {\n super.transfer(to, amount);\n emit Transfer(msg.sender, to, amount, data);\n if (to.code.length > 0) {\n IERC677Receiver(to).onTokenTransfer(msg.sender, amount, data);\n }\n return true;\n }\n}\n" + }, + "src/libs/OwnerIsCreator.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ConfirmedOwner} from \"./ConfirmedOwner.sol\";\n\n/// @title The OwnerIsCreator contract\n/// @notice A contract with helpers for basic contract ownership.\ncontract OwnerIsCreator is ConfirmedOwner {\n constructor() ConfirmedOwner(msg.sender) {}\n}\n" + } + }, + "settings": { + "evmVersion": "london", + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/hardhat/deployments/ethereum/.chainId b/hardhat/deployments/ethereum/.chainId new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/hardhat/deployments/ethereum/.chainId @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/hardhat/deployments/ethereum/LDY.json b/hardhat/deployments/ethereum/LDY.json new file mode 100644 index 0000000..46852af --- /dev/null +++ b/hardhat/deployments/ethereum/LDY.json @@ -0,0 +1,1177 @@ +{ + "address": "0x482dF7483a52496F4C65AB499966dfcdf4DDFDbc", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimals_", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "maxSupply_", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "supplyAfterMint", + "type": "uint256" + } + ], + "name": "MaxSupplyExceeded", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "SenderNotBurner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "SenderNotMinter", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "burner", + "type": "address" + } + ], + "name": "BurnAccessGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "burner", + "type": "address" + } + ], + "name": "BurnAccessRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "MintAccessGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "MintAccessRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "OwnershipTransferRequested", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burnFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseApproval", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getBurners", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMinters", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "burner", + "type": "address" + } + ], + "name": "grantBurnRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "burnAndMinter", + "type": "address" + } + ], + "name": "grantMintAndBurnRoles", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "grantMintRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseApproval", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "burner", + "type": "address" + } + ], + "name": "isBurner", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "isMinter", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "burner", + "type": "address" + } + ], + "name": "revokeBurnRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "revokeMintRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "transferAndCall", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xce05a81d4508993299918857d78a1acd306f29d97cc343c1b66b4356742f2904", + "receipt": { + "to": "0x30Fa557608017afB6E8e4ABe8027787C00473FF0", + "from": "0x65b1B95F7b886c87Eb04E70bfE73D00fc640b046", + "contractAddress": "0x482dF7483a52496F4C65AB499966dfcdf4DDFDbc", + "transactionIndex": 32, + "gasUsed": "1487364", + "logsBloom": "0x00000000400000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000004000000004000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xcc3767598d0a7c14eeef778b9a8959e712590bed644ec73fa3e52b3f40a3cdee", + "transactionHash": "0xce05a81d4508993299918857d78a1acd306f29d97cc343c1b66b4356742f2904", + "logs": [ + { + "transactionIndex": 32, + "blockNumber": 19819133, + "transactionHash": "0xce05a81d4508993299918857d78a1acd306f29d97cc343c1b66b4356742f2904", + "address": "0x30Fa557608017afB6E8e4ABe8027787C00473FF0", + "topics": [ + "0x4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b511" + ], + "data": "0x000000000000000000000000482df7483a52496f4c65ab499966dfcdf4ddfdbc", + "logIndex": 97, + "blockHash": "0xcc3767598d0a7c14eeef778b9a8959e712590bed644ec73fa3e52b3f40a3cdee" + }, + { + "transactionIndex": 32, + "blockNumber": 19819133, + "transactionHash": "0xce05a81d4508993299918857d78a1acd306f29d97cc343c1b66b4356742f2904", + "address": "0x30Fa557608017afB6E8e4ABe8027787C00473FF0", + "topics": [ + "0x442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e" + ], + "data": "0x18d8953dbbb0a31db7749c43a075add2877b3bf409b945b63f75f903ca7018a50000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 98, + "blockHash": "0xcc3767598d0a7c14eeef778b9a8959e712590bed644ec73fa3e52b3f40a3cdee" + } + ], + "blockNumber": 19819133, + "cumulativeGasUsed": "4670752", + "status": 1, + "byzantium": true + }, + "args": [ + "Ledgity Token", + "LDY", + 18, + "75000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "d8b5802e009f6fee7aed14d8582e28a9", + "metadata": "{\"compiler\":{\"version\":\"0.8.20+commit.a1b79de6\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"decimals_\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"maxSupply_\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"supplyAfterMint\",\"type\":\"uint256\"}],\"name\":\"MaxSupplyExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotBurner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotMinter\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"BurnAccessGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"BurnAccessRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MintAccessGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MintAccessRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseApproval\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBurners\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMinters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"grantBurnRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"burnAndMinter\",\"type\":\"address\"}],\"name\":\"grantMintAndBurnRoles\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"grantMintRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseApproval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"isBurner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"revokeBurnRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"revokeMintRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"transferAndCall\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"The total supply can be limited during deployment.\",\"events\":{\"Approval(address,address,uint256)\":{\"details\":\"Emitted when the allowance of a `spender` for an `owner` is set by a call to {approve}. `value` is the new allowance.\"},\"Transfer(address,address,uint256)\":{\"details\":\"Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero.\"}},\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burn(address,uint256)\":{\"details\":\"Alias for BurnFrom for compatibility with the older naming convention.Uses burnFrom for all validation & logic.\",\"params\":{\"account\":\"The address to burn tokens from.\",\"amount\":\"The number of tokens to be burned.\"}},\"burn(uint256)\":{\"details\":\"Uses OZ ERC20 _burn to disallow burning from address(0).Decreases the total supply.\"},\"burnFrom(address,uint256)\":{\"details\":\"Uses OZ ERC20 _burn to disallow burning from address(0).Decreases the total supply.\"},\"decimals()\":{\"details\":\"Returns the number of decimals used in its user representation.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"decreaseApproval(address,uint256)\":{\"details\":\"Exists to be backwards compatible with the older naming convention.\"},\"grantBurnRole(address)\":{\"details\":\"only the owner can call this function.\"},\"grantMintAndBurnRoles(address)\":{\"details\":\"calls public functions so this function does not require access controls. This is handled in the inner functions.\"},\"grantMintRole(address)\":{\"details\":\"only the owner can call this function.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"increaseApproval(address,uint256)\":{\"details\":\"Exists to be backwards compatible with the older naming convention.\"},\"isBurner(address)\":{\"returns\":{\"_0\":\"true if the address is allowed to burn.\"}},\"isMinter(address)\":{\"returns\":{\"_0\":\"true if the address is allowed to mint.\"}},\"maxSupply()\":{\"details\":\"Returns the max supply of the token, 0 if unlimited.\"},\"mint(address,uint256)\":{\"details\":\"Uses OZ ERC20 _mint to disallow minting to address(0).Disallows minting to address(this)Increases the total supply.\",\"params\":{\"account\":\"The address to mint the new tokens to.\",\"amount\":\"The number of tokens to be minted.\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"revokeBurnRole(address)\":{\"details\":\"only the owner can call this function\"},\"revokeMintRole(address)\":{\"details\":\"only the owner can call this function.\"},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferAndCall(address,uint256,bytes)\":{\"params\":{\"amount\":\"The amount of tokens to be transferred\",\"data\":\"bytes Additional data with no specified format, sent in call to `to`\",\"to\":\"The address which you want to transfer to\"},\"returns\":{\"success\":\"true unless throwing\"}},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"}},\"stateVariables\":{\"i_decimals\":{\"details\":\"The number of decimals for the token\"},\"i_maxSupply\":{\"details\":\"The maximum supply of the token, 0 if unlimited\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"acceptOwnership()\":{\"notice\":\"Allows an ownership transfer to be completed by the recipient.\"},\"burn(address,uint256)\":{\"notice\":\"Burns tokens from a given address..\"},\"getBurners()\":{\"notice\":\"Returns all permissioned burners\"},\"getMinters()\":{\"notice\":\"Returns all permissioned minters\"},\"grantBurnRole(address)\":{\"notice\":\"Grants burn role to the given address.\"},\"grantMintAndBurnRoles(address)\":{\"notice\":\"grants both mint and burn roles to `burnAndMinter`.\"},\"grantMintRole(address)\":{\"notice\":\"Grants mint role to the given address.\"},\"isBurner(address)\":{\"notice\":\"Checks whether a given address is a burner for this token.\"},\"isMinter(address)\":{\"notice\":\"Checks whether a given address is a minter for this token.\"},\"mint(address,uint256)\":{\"notice\":\"Mints new tokens for a given address.\"},\"owner()\":{\"notice\":\"Get the current owner\"},\"revokeBurnRole(address)\":{\"notice\":\"Revokes burn role from the given address.\"},\"revokeMintRole(address)\":{\"notice\":\"Revokes mint role for the given address.\"},\"transferAndCall(address,uint256,bytes)\":{\"notice\":\"Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver\"},\"transferOwnership(address)\":{\"notice\":\"Allows an owner to begin transferring ownership to a new address, pending.\"}},\"notice\":\"A basic ERC677 compatible token contract with burn and minting roles.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/LDY.sol\":\"LDY\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"./extensions/IERC20Metadata.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20, IERC20Metadata {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\\n // decrementing then incrementing.\\n _balances[to] += amount;\\n }\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n unchecked {\\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\\n _balances[account] += amount;\\n }\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n // Overflow not possible: amount <= accountBalance <= totalSupply.\\n _totalSupply -= amount;\\n }\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"keccak256\":\"0x4ffc0547c02ad22925310c585c0f166f8759e2648a09e9b489100c42f15dd98d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"keccak256\":\"0x0d19410453cda55960a818e02bd7c18952a5c8fe7a3036e81f0d599f34487a7b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xc3ff3f5c4584e1d9a483ad7ced51ab64523201f4e3d3c65293e4ca8aeb77a961\",\"license\":\"MIT\"},\"src/LDY.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IBurnMintERC20} from \\\"./interfaces/IBurnMintERC20.sol\\\";\\nimport {IERC677} from \\\"./interfaces/IERC677.sol\\\";\\n\\nimport {ERC677} from \\\"./libs/ERC677.sol\\\";\\nimport {OwnerIsCreator} from \\\"./libs/OwnerIsCreator.sol\\\";\\n\\nimport {ERC20Burnable} from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport {EnumerableSet} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {IERC165} from \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/**\\n * @title LDY\\n * @dev The $LDY is the utility and governance token of the entire Ledgity ecosystem.\\n *\\n * This contract is taken from the official Chainlink CCIP cross-chain token template:\\n * https://github.com/smartcontractkit/ccip/blob/onchain-release/v1.1.0/contracts/src/v0.8/shared/token/ERC677/BurnMintERC677.sol\\n * \\n * No changes have been made to the original contract; only the imports and folder\\n * structure have been reworked. This was done to eliminate hundreds of unused files\\n * and to import OpenZeppelin libraries directly from their NPM package.\\n *\\n * $LDY token is non-upgradeable, non-pausable, and non-restrictable.\\n *\\n * Specs:\\n * - Name: Ledgity Token\\n * - Symbol: LDY\\n * - Decimals: 18\\n * - Total supply: 75,000,000\\n *\\n * @custom:security-contact security@ledgity.com\\n */\\n\\n/// @notice A basic ERC677 compatible token contract with burn and minting roles.\\n/// @dev The total supply can be limited during deployment.\\ncontract LDY is IBurnMintERC20, ERC677, IERC165, ERC20Burnable, OwnerIsCreator {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n error SenderNotMinter(address sender);\\n error SenderNotBurner(address sender);\\n error MaxSupplyExceeded(uint256 supplyAfterMint);\\n\\n event MintAccessGranted(address indexed minter);\\n event BurnAccessGranted(address indexed burner);\\n event MintAccessRevoked(address indexed minter);\\n event BurnAccessRevoked(address indexed burner);\\n\\n // @dev the allowed minter addresses\\n EnumerableSet.AddressSet internal s_minters;\\n // @dev the allowed burner addresses\\n EnumerableSet.AddressSet internal s_burners;\\n\\n /// @dev The number of decimals for the token\\n uint8 internal immutable i_decimals;\\n\\n /// @dev The maximum supply of the token, 0 if unlimited\\n uint256 internal immutable i_maxSupply;\\n\\n constructor(string memory name, string memory symbol, uint8 decimals_, uint256 maxSupply_) ERC677(name, symbol) {\\n i_decimals = decimals_;\\n i_maxSupply = maxSupply_;\\n }\\n\\n function supportsInterface(bytes4 interfaceId) public pure virtual override returns (bool) {\\n return\\n interfaceId == type(IERC20).interfaceId ||\\n interfaceId == type(IERC677).interfaceId ||\\n interfaceId == type(IBurnMintERC20).interfaceId ||\\n interfaceId == type(IERC165).interfaceId;\\n }\\n\\n // ================================================================\\n // | ERC20 |\\n // ================================================================\\n\\n /// @dev Returns the number of decimals used in its user representation.\\n function decimals() public view virtual override returns (uint8) {\\n return i_decimals;\\n }\\n\\n /// @dev Returns the max supply of the token, 0 if unlimited.\\n function maxSupply() public view virtual returns (uint256) {\\n return i_maxSupply;\\n }\\n\\n /// @dev Uses OZ ERC20 _transfer to disallow sending to address(0).\\n /// @dev Disallows sending to address(this)\\n function _transfer(address from, address to, uint256 amount) internal virtual override validAddress(to) {\\n super._transfer(from, to, amount);\\n }\\n\\n /// @dev Uses OZ ERC20 _approve to disallow approving for address(0).\\n /// @dev Disallows approving for address(this)\\n function _approve(address owner, address spender, uint256 amount) internal virtual override validAddress(spender) {\\n super._approve(owner, spender, amount);\\n }\\n\\n /// @dev Exists to be backwards compatible with the older naming convention.\\n function decreaseApproval(address spender, uint256 subtractedValue) external returns (bool success) {\\n return decreaseAllowance(spender, subtractedValue);\\n }\\n\\n /// @dev Exists to be backwards compatible with the older naming convention.\\n function increaseApproval(address spender, uint256 addedValue) external {\\n increaseAllowance(spender, addedValue);\\n }\\n\\n /// @notice Check if recipient is valid (not this contract address).\\n /// @param recipient the account we transfer/approve to.\\n /// @dev Reverts with an empty revert to be compatible with the existing link token when\\n /// the recipient is this contract address.\\n modifier validAddress(address recipient) virtual {\\n // solhint-disable-next-line reason-string, custom-errors\\n if (recipient == address(this)) revert();\\n _;\\n }\\n\\n // ================================================================\\n // | Burning & minting |\\n // ================================================================\\n\\n /// @inheritdoc ERC20Burnable\\n /// @dev Uses OZ ERC20 _burn to disallow burning from address(0).\\n /// @dev Decreases the total supply.\\n function burn(uint256 amount) public override(IBurnMintERC20, ERC20Burnable) onlyBurner {\\n super.burn(amount);\\n }\\n\\n /// @inheritdoc IBurnMintERC20\\n /// @dev Alias for BurnFrom for compatibility with the older naming convention.\\n /// @dev Uses burnFrom for all validation & logic.\\n function burn(address account, uint256 amount) public virtual override {\\n burnFrom(account, amount);\\n }\\n\\n /// @inheritdoc ERC20Burnable\\n /// @dev Uses OZ ERC20 _burn to disallow burning from address(0).\\n /// @dev Decreases the total supply.\\n function burnFrom(address account, uint256 amount) public override(IBurnMintERC20, ERC20Burnable) onlyBurner {\\n super.burnFrom(account, amount);\\n }\\n\\n /// @inheritdoc IBurnMintERC20\\n /// @dev Uses OZ ERC20 _mint to disallow minting to address(0).\\n /// @dev Disallows minting to address(this)\\n /// @dev Increases the total supply.\\n function mint(address account, uint256 amount) external override onlyMinter validAddress(account) {\\n if (i_maxSupply != 0 && totalSupply() + amount > i_maxSupply) revert MaxSupplyExceeded(totalSupply() + amount);\\n\\n _mint(account, amount);\\n }\\n\\n // ================================================================\\n // | Roles |\\n // ================================================================\\n\\n /// @notice grants both mint and burn roles to `burnAndMinter`.\\n /// @dev calls public functions so this function does not require\\n /// access controls. This is handled in the inner functions.\\n function grantMintAndBurnRoles(address burnAndMinter) external {\\n grantMintRole(burnAndMinter);\\n grantBurnRole(burnAndMinter);\\n }\\n\\n /// @notice Grants mint role to the given address.\\n /// @dev only the owner can call this function.\\n function grantMintRole(address minter) public onlyOwner {\\n if (s_minters.add(minter)) {\\n emit MintAccessGranted(minter);\\n }\\n }\\n\\n /// @notice Grants burn role to the given address.\\n /// @dev only the owner can call this function.\\n function grantBurnRole(address burner) public onlyOwner {\\n if (s_burners.add(burner)) {\\n emit BurnAccessGranted(burner);\\n }\\n }\\n\\n /// @notice Revokes mint role for the given address.\\n /// @dev only the owner can call this function.\\n function revokeMintRole(address minter) public onlyOwner {\\n if (s_minters.remove(minter)) {\\n emit MintAccessRevoked(minter);\\n }\\n }\\n\\n /// @notice Revokes burn role from the given address.\\n /// @dev only the owner can call this function\\n function revokeBurnRole(address burner) public onlyOwner {\\n if (s_burners.remove(burner)) {\\n emit BurnAccessRevoked(burner);\\n }\\n }\\n\\n /// @notice Returns all permissioned minters\\n function getMinters() public view returns (address[] memory) {\\n return s_minters.values();\\n }\\n\\n /// @notice Returns all permissioned burners\\n function getBurners() public view returns (address[] memory) {\\n return s_burners.values();\\n }\\n\\n // ================================================================\\n // | Access |\\n // ================================================================\\n\\n /// @notice Checks whether a given address is a minter for this token.\\n /// @return true if the address is allowed to mint.\\n function isMinter(address minter) public view returns (bool) {\\n return s_minters.contains(minter);\\n }\\n\\n /// @notice Checks whether a given address is a burner for this token.\\n /// @return true if the address is allowed to burn.\\n function isBurner(address burner) public view returns (bool) {\\n return s_burners.contains(burner);\\n }\\n\\n /// @notice Checks whether the msg.sender is a permissioned minter for this token\\n /// @dev Reverts with a SenderNotMinter if the check fails\\n modifier onlyMinter() {\\n if (!isMinter(msg.sender)) revert SenderNotMinter(msg.sender);\\n _;\\n }\\n\\n /// @notice Checks whether the msg.sender is a permissioned burner for this token\\n /// @dev Reverts with a SenderNotBurner if the check fails\\n modifier onlyBurner() {\\n if (!isBurner(msg.sender)) revert SenderNotBurner(msg.sender);\\n _;\\n }\\n}\\n\",\"keccak256\":\"0xed068708e5c2e87ad74caa7c73a97bc02a106ea5d62698234754f63933abf6b5\",\"license\":\"MIT\"},\"src/interfaces/IBurnMintERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IBurnMintERC20 is IERC20 {\\n /// @notice Mints new tokens for a given address.\\n /// @param account The address to mint the new tokens to.\\n /// @param amount The number of tokens to be minted.\\n /// @dev this function increases the total supply.\\n function mint(address account, uint256 amount) external;\\n\\n /// @notice Burns tokens from the sender.\\n /// @param amount The number of tokens to be burned.\\n /// @dev this function decreases the total supply.\\n function burn(uint256 amount) external;\\n\\n /// @notice Burns tokens from a given address..\\n /// @param account The address to burn tokens from.\\n /// @param amount The number of tokens to be burned.\\n /// @dev this function decreases the total supply.\\n function burn(address account, uint256 amount) external;\\n\\n /// @notice Burns tokens from a given address..\\n /// @param account The address to burn tokens from.\\n /// @param amount The number of tokens to be burned.\\n /// @dev this function decreases the total supply.\\n function burnFrom(address account, uint256 amount) external;\\n}\\n\",\"keccak256\":\"0x8adc632df6a61f0ca93c3be6e25b0334247bfe48fc339ce92b85155766b614bb\",\"license\":\"MIT\"},\"src/interfaces/IERC677.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IERC677 {\\n event Transfer(address indexed from, address indexed to, uint256 value, bytes data);\\n\\n /// @notice Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver\\n /// @param to The address which you want to transfer to\\n /// @param amount The amount of tokens to be transferred\\n /// @param data bytes Additional data with no specified format, sent in call to `to`\\n /// @return true unless throwing\\n function transferAndCall(address to, uint256 amount, bytes memory data) external returns (bool);\\n}\\n\",\"keccak256\":\"0x771321adbdab6bec7d27bcd8a46dfea813f1c97d97a7a671fe35cd87744daee4\",\"license\":\"MIT\"},\"src/interfaces/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.6;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(address sender, uint256 amount, bytes calldata data) external;\\n}\",\"keccak256\":\"0xddc2a487ff19419029168dd870fff6ab8075446948a404276edc7d053e6f9f35\",\"license\":\"MIT\"},\"src/interfaces/IOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IOwnable {\\n function owner() external returns (address);\\n\\n function transferOwnership(address recipient) external;\\n\\n function acceptOwnership() external;\\n}\",\"keccak256\":\"0x15a45e18786bd5f5158260f7b225daf428f76c4d34284d851c4e480f66b13f25\",\"license\":\"MIT\"},\"src/libs/ConfirmedOwner.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ConfirmedOwnerWithProposal.sol\\\";\\n\\n/**\\n * @title The ConfirmedOwner contract\\n * @notice A contract with helpers for basic contract ownership.\\n */\\ncontract ConfirmedOwner is ConfirmedOwnerWithProposal {\\n constructor(address newOwner) ConfirmedOwnerWithProposal(newOwner, address(0)) {}\\n}\",\"keccak256\":\"0x57960637d0ac27af34cde3f0aa709e49f8ae109697695ec73117dfb6d8a4271d\",\"license\":\"MIT\"},\"src/libs/ConfirmedOwnerWithProposal.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"../interfaces/IOwnable.sol\\\";\\n\\n/**\\n * @title The ConfirmedOwner contract\\n * @notice A contract with helpers for basic contract ownership.\\n */\\ncontract ConfirmedOwnerWithProposal is IOwnable {\\n address private s_owner;\\n address private s_pendingOwner;\\n\\n event OwnershipTransferRequested(address indexed from, address indexed to);\\n event OwnershipTransferred(address indexed from, address indexed to);\\n\\n constructor(address newOwner, address pendingOwner) {\\n require(newOwner != address(0), \\\"Cannot set owner to zero\\\");\\n\\n s_owner = newOwner;\\n if (pendingOwner != address(0)) {\\n _transferOwnership(pendingOwner);\\n }\\n }\\n\\n /**\\n * @notice Allows an owner to begin transferring ownership to a new address,\\n * pending.\\n */\\n function transferOwnership(address to) public override onlyOwner {\\n _transferOwnership(to);\\n }\\n\\n /**\\n * @notice Allows an ownership transfer to be completed by the recipient.\\n */\\n function acceptOwnership() external override {\\n require(msg.sender == s_pendingOwner, \\\"Must be proposed owner\\\");\\n\\n address oldOwner = s_owner;\\n s_owner = msg.sender;\\n s_pendingOwner = address(0);\\n\\n emit OwnershipTransferred(oldOwner, msg.sender);\\n }\\n\\n /**\\n * @notice Get the current owner\\n */\\n function owner() public view override returns (address) {\\n return s_owner;\\n }\\n\\n /**\\n * @notice validate, transfer ownership, and emit relevant events\\n */\\n function _transferOwnership(address to) private {\\n require(to != msg.sender, \\\"Cannot transfer to self\\\");\\n\\n s_pendingOwner = to;\\n\\n emit OwnershipTransferRequested(s_owner, to);\\n }\\n\\n /**\\n * @notice validate access\\n */\\n function _validateOwnership() internal view {\\n require(msg.sender == s_owner, \\\"Only callable by owner\\\");\\n }\\n\\n /**\\n * @notice Reverts if called by anyone other than the contract owner.\\n */\\n modifier onlyOwner() {\\n _validateOwnership();\\n _;\\n }\\n}\",\"keccak256\":\"0x1a48a2386fff0c1068a2eed4decbf0f53b3ea8a77a088fa0a9f033a1688b967f\",\"license\":\"MIT\"},\"src/libs/ERC677.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.0;\\n\\nimport {IERC677} from \\\"../interfaces/IERC677.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/IERC677Receiver.sol\\\";\\n\\nimport {ERC20} from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\n\\ncontract ERC677 is IERC677, ERC20 {\\n constructor(string memory name, string memory symbol) ERC20(name, symbol) {}\\n\\n /// @inheritdoc IERC677\\n function transferAndCall(address to, uint256 amount, bytes memory data) public returns (bool success) {\\n super.transfer(to, amount);\\n emit Transfer(msg.sender, to, amount, data);\\n if (to.code.length > 0) {\\n IERC677Receiver(to).onTokenTransfer(msg.sender, amount, data);\\n }\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xe18487d77f4f20750733acff95919cd1f40e8dd32cfd9440e46ef88e4933ffbd\",\"license\":\"UNLICENSED\"},\"src/libs/OwnerIsCreator.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ConfirmedOwner} from \\\"./ConfirmedOwner.sol\\\";\\n\\n/// @title The OwnerIsCreator contract\\n/// @notice A contract with helpers for basic contract ownership.\\ncontract OwnerIsCreator is ConfirmedOwner {\\n constructor() ConfirmedOwner(msg.sender) {}\\n}\\n\",\"keccak256\":\"0x895af02d6a3df2930bbb6ec1f2d68118b492ca6e710ba0c34fcb6b574a0906aa\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60c06040523480156200001157600080fd5b5060405162001c2a38038062001c2a833981016040819052620000349162000277565b338060008686818160036200004a838262000391565b50600462000059828262000391565b5050506001600160a01b0384169150620000bc90505760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600580546001600160a01b0319166001600160a01b0384811691909117909155811615620000ef57620000ef8162000106565b50505060ff90911660805260a052506200045d9050565b336001600160a01b03821603620001605760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000b3565b600680546001600160a01b0319166001600160a01b03838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001da57600080fd5b81516001600160401b0380821115620001f757620001f7620001b2565b604051601f8301601f19908116603f01168101908282118183101715620002225762000222620001b2565b816040528381526020925086838588010111156200023f57600080fd5b600091505b8382101562000263578582018301518183018401529082019062000244565b600093810190920192909252949350505050565b600080600080608085870312156200028e57600080fd5b84516001600160401b0380821115620002a657600080fd5b620002b488838901620001c8565b95506020870151915080821115620002cb57600080fd5b50620002da87828801620001c8565b935050604085015160ff81168114620002f257600080fd5b6060959095015193969295505050565b600181811c908216806200031757607f821691505b6020821081036200033857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200038c57600081815260208120601f850160051c81016020861015620003675750805b601f850160051c820191505b81811015620003885782815560010162000373565b5050505b505050565b81516001600160401b03811115620003ad57620003ad620001b2565b620003c581620003be845462000302565b846200033e565b602080601f831160018114620003fd5760008415620003e45750858301515b600019600386901b1c1916600185901b17855562000388565b600085815260208120601f198616915b828110156200042e578886015182559484019460019091019084016200040d565b50858210156200044d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a051611799620004916000396000818161042d01528181610715015261073f0152600061027101526117996000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c806379cc67901161010f578063c2e3273d116100a2578063d73dd62311610071578063d73dd62314610451578063dd62ed3e14610464578063f2fde38b14610477578063f81094f31461048a57600080fd5b8063c2e3273d146103f2578063c630948d14610405578063c64d0ebc14610418578063d5abeb011461042b57600080fd5b80639dc29fac116100de5780639dc29fac146103a6578063a457c2d7146103b9578063a9059cbb146103cc578063aa271e1a146103df57600080fd5b806379cc67901461036857806386fe8b431461037b5780638da5cb5b1461038357806395d89b411461039e57600080fd5b806340c10f19116101875780636618846311610156578063661884631461030f5780636b32810b1461032257806370a082311461033757806379ba50971461036057600080fd5b806340c10f19146102c157806342966c68146102d65780634334614a146102e95780634f5632f8146102fc57600080fd5b806323b872dd116101c357806323b872dd14610257578063313ce5671461026a578063395093511461029b5780634000aea0146102ae57600080fd5b806301ffc9a7146101f557806306fdde031461021d578063095ea7b31461023257806318160ddd14610245575b600080fd5b6102086102033660046113d6565b61049d565b60405190151581526020015b60405180910390f35b61022561050a565b6040516102149190611446565b610208610240366004611475565b61059c565b6002545b604051908152602001610214565b61020861026536600461149f565b6105b4565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610214565b6102086102a9366004611475565b6105d8565b6102086102bc3660046114f1565b6105fa565b6102d46102cf366004611475565b6106d0565b005b6102d46102e43660046115bc565b6107b8565b6102086102f73660046115d5565b6107ec565b6102d461030a3660046115d5565b6107f9565b61020861031d366004611475565b610848565b61032a61085b565b60405161021491906115f0565b6102496103453660046115d5565b6001600160a01b031660009081526020819052604090205490565b6102d461086c565b6102d4610376366004611475565b61091a565b61032a610950565b6005546040516001600160a01b039091168152602001610214565b61022561095c565b6102d46103b4366004611475565b61096b565b6102086103c7366004611475565b610975565b6102086103da366004611475565b6109f0565b6102086103ed3660046115d5565b6109fe565b6102d46104003660046115d5565b610a0b565b6102d46104133660046115d5565b610a5a565b6102d46104263660046115d5565b610a68565b7f0000000000000000000000000000000000000000000000000000000000000000610249565b6102d461045f366004611475565b610ab7565b61024961047236600461163d565b610ac1565b6102d46104853660046115d5565b610aec565b6102d46104983660046115d5565b610afd565b60006001600160e01b031982166336372b0760e01b14806104ce57506001600160e01b03198216630200057560e51b145b806104e957506001600160e01b0319821663e6599b4d60e01b145b8061050457506001600160e01b031982166301ffc9a760e01b145b92915050565b60606003805461051990611670565b80601f016020809104026020016040519081016040528092919081815260200182805461054590611670565b80156105925780601f1061056757610100808354040283529160200191610592565b820191906000526020600020905b81548152906001019060200180831161057557829003601f168201915b5050505050905090565b6000336105aa818585610b4c565b5060019392505050565b6000336105c2858285610b73565b6105cd858585610be7565b506001949350505050565b6000336105aa8185856105eb8383610ac1565b6105f591906116c0565b610b4c565b600061060684846109f0565b50836001600160a01b0316336001600160a01b03167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16858560405161064c9291906116d3565b60405180910390a36001600160a01b0384163b156105aa57604051635260769b60e11b81526001600160a01b0385169063a4c0ed3690610694903390879087906004016116f4565b600060405180830381600087803b1580156106ae57600080fd5b505af11580156106c2573d6000803e3d6000fd5b505050505060019392505050565b6106d9336109fe565b6106fd5760405163e2c8c9d560e01b81523360048201526024015b60405180910390fd5b81306001600160a01b0382160361071357600080fd5b7f00000000000000000000000000000000000000000000000000000000000000001580159061077457507f00000000000000000000000000000000000000000000000000000000000000008261076860025490565b61077291906116c0565b115b156107a9578161078360025490565b61078d91906116c0565b60405163cbbf111360e01b81526004016106f491815260200190565b6107b38383610c08565b505050565b6107c1336107ec565b6107e05760405163c820b10b60e01b81523360048201526024016106f4565b6107e981610cc7565b50565b6000610504600983610cd1565b610801610cf3565b61080c600982610d48565b156107e9576040516001600160a01b038216907f0a675452746933cefe3d74182e78db7afe57ba60eaa4234b5d85e9aa41b0610c90600090a250565b60006108548383610975565b9392505050565b60606108676007610d5d565b905090565b6006546001600160a01b031633146108bf5760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b60448201526064016106f4565b600580546001600160a01b0319808216339081179093556006805490911690556040516001600160a01b03909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b610923336107ec565b6109425760405163c820b10b60e01b81523360048201526024016106f4565b61094c8282610d6a565b5050565b60606108676009610d5d565b60606004805461051990611670565b61094c828261091a565b600033816109838286610ac1565b9050838110156109e35760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016106f4565b6105cd8286868403610b4c565b6000336105aa818585610be7565b6000610504600783610cd1565b610a13610cf3565b610a1e600782610d7f565b156107e9576040516001600160a01b038216907fe46fef8bbff1389d9010703cf8ebb363fb3daf5bf56edc27080b67bc8d9251ea90600090a250565b610a6381610a0b565b6107e9815b610a70610cf3565b610a7b600982610d7f565b156107e9576040516001600160a01b038216907f92308bb7573b2a3d17ddb868b39d8ebec433f3194421abc22d084f89658c9bad90600090a250565b6107b382826105d8565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610af4610cf3565b6107e981610d94565b610b05610cf3565b610b10600782610d48565b156107e9576040516001600160a01b038216907fed998b960f6340d045f620c119730f7aa7995e7425c2401d3a5b64ff998a59e990600090a250565b81306001600160a01b03821603610b6257600080fd5b610b6d848484610e3e565b50505050565b6000610b7f8484610ac1565b90506000198114610b6d5781811015610bda5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106f4565b610b6d8484848403610b4c565b81306001600160a01b03821603610bfd57600080fd5b610b6d848484610f62565b6001600160a01b038216610c5e5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106f4565b8060026000828254610c7091906116c0565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6107e93382611106565b6001600160a01b03811660009081526001830160205260408120541515610854565b6005546001600160a01b03163314610d465760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b60448201526064016106f4565b565b6000610854836001600160a01b038416611238565b606060006108548361132b565b610d75823383610b73565b61094c8282611106565b6000610854836001600160a01b038416611387565b336001600160a01b03821603610dec5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106f4565b600680546001600160a01b0319166001600160a01b03838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b6001600160a01b038316610ea05760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016106f4565b6001600160a01b038216610f015760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016106f4565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b038316610fc65760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016106f4565b6001600160a01b0382166110285760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016106f4565b6001600160a01b038316600090815260208190526040902054818110156110a05760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016106f4565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610b6d565b6001600160a01b0382166111665760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016106f4565b6001600160a01b038216600090815260208190526040902054818110156111da5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016106f4565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6000818152600183016020526040812054801561132157600061125c600183611724565b855490915060009061127090600190611724565b90508181146112d557600086600001828154811061129057611290611737565b90600052602060002001549050808760000184815481106112b3576112b3611737565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806112e6576112e661174d565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610504565b6000915050610504565b60608160000180548060200260200160405190810160405280929190818152602001828054801561137b57602002820191906000526020600020905b815481526020019060010190808311611367575b50505050509050919050565b60008181526001830160205260408120546113ce57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610504565b506000610504565b6000602082840312156113e857600080fd5b81356001600160e01b03198116811461085457600080fd5b6000815180845260005b818110156114265760208185018101518683018201520161140a565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006108546020830184611400565b80356001600160a01b038116811461147057600080fd5b919050565b6000806040838503121561148857600080fd5b61149183611459565b946020939093013593505050565b6000806000606084860312156114b457600080fd5b6114bd84611459565b92506114cb60208501611459565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b60008060006060848603121561150657600080fd5b61150f84611459565b925060208401359150604084013567ffffffffffffffff8082111561153357600080fd5b818601915086601f83011261154757600080fd5b813581811115611559576115596114db565b604051601f8201601f19908116603f01168101908382118183101715611581576115816114db565b8160405282815289602084870101111561159a57600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b6000602082840312156115ce57600080fd5b5035919050565b6000602082840312156115e757600080fd5b61085482611459565b6020808252825182820181905260009190848201906040850190845b818110156116315783516001600160a01b03168352928401929184019160010161160c565b50909695505050505050565b6000806040838503121561165057600080fd5b61165983611459565b915061166760208401611459565b90509250929050565b600181811c9082168061168457607f821691505b6020821081036116a457634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610504576105046116aa565b8281526040602082015260006116ec6040830184611400565b949350505050565b60018060a01b038416815282602082015260606040820152600061171b6060830184611400565b95945050505050565b81810381811115610504576105046116aa565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fdfea264697066735822122026bf827ff7c4546d08bc173f7cb82c7ccf3be629370907c1d7e2e74f372b4c0164736f6c63430008140033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101f05760003560e01c806379cc67901161010f578063c2e3273d116100a2578063d73dd62311610071578063d73dd62314610451578063dd62ed3e14610464578063f2fde38b14610477578063f81094f31461048a57600080fd5b8063c2e3273d146103f2578063c630948d14610405578063c64d0ebc14610418578063d5abeb011461042b57600080fd5b80639dc29fac116100de5780639dc29fac146103a6578063a457c2d7146103b9578063a9059cbb146103cc578063aa271e1a146103df57600080fd5b806379cc67901461036857806386fe8b431461037b5780638da5cb5b1461038357806395d89b411461039e57600080fd5b806340c10f19116101875780636618846311610156578063661884631461030f5780636b32810b1461032257806370a082311461033757806379ba50971461036057600080fd5b806340c10f19146102c157806342966c68146102d65780634334614a146102e95780634f5632f8146102fc57600080fd5b806323b872dd116101c357806323b872dd14610257578063313ce5671461026a578063395093511461029b5780634000aea0146102ae57600080fd5b806301ffc9a7146101f557806306fdde031461021d578063095ea7b31461023257806318160ddd14610245575b600080fd5b6102086102033660046113d6565b61049d565b60405190151581526020015b60405180910390f35b61022561050a565b6040516102149190611446565b610208610240366004611475565b61059c565b6002545b604051908152602001610214565b61020861026536600461149f565b6105b4565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610214565b6102086102a9366004611475565b6105d8565b6102086102bc3660046114f1565b6105fa565b6102d46102cf366004611475565b6106d0565b005b6102d46102e43660046115bc565b6107b8565b6102086102f73660046115d5565b6107ec565b6102d461030a3660046115d5565b6107f9565b61020861031d366004611475565b610848565b61032a61085b565b60405161021491906115f0565b6102496103453660046115d5565b6001600160a01b031660009081526020819052604090205490565b6102d461086c565b6102d4610376366004611475565b61091a565b61032a610950565b6005546040516001600160a01b039091168152602001610214565b61022561095c565b6102d46103b4366004611475565b61096b565b6102086103c7366004611475565b610975565b6102086103da366004611475565b6109f0565b6102086103ed3660046115d5565b6109fe565b6102d46104003660046115d5565b610a0b565b6102d46104133660046115d5565b610a5a565b6102d46104263660046115d5565b610a68565b7f0000000000000000000000000000000000000000000000000000000000000000610249565b6102d461045f366004611475565b610ab7565b61024961047236600461163d565b610ac1565b6102d46104853660046115d5565b610aec565b6102d46104983660046115d5565b610afd565b60006001600160e01b031982166336372b0760e01b14806104ce57506001600160e01b03198216630200057560e51b145b806104e957506001600160e01b0319821663e6599b4d60e01b145b8061050457506001600160e01b031982166301ffc9a760e01b145b92915050565b60606003805461051990611670565b80601f016020809104026020016040519081016040528092919081815260200182805461054590611670565b80156105925780601f1061056757610100808354040283529160200191610592565b820191906000526020600020905b81548152906001019060200180831161057557829003601f168201915b5050505050905090565b6000336105aa818585610b4c565b5060019392505050565b6000336105c2858285610b73565b6105cd858585610be7565b506001949350505050565b6000336105aa8185856105eb8383610ac1565b6105f591906116c0565b610b4c565b600061060684846109f0565b50836001600160a01b0316336001600160a01b03167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16858560405161064c9291906116d3565b60405180910390a36001600160a01b0384163b156105aa57604051635260769b60e11b81526001600160a01b0385169063a4c0ed3690610694903390879087906004016116f4565b600060405180830381600087803b1580156106ae57600080fd5b505af11580156106c2573d6000803e3d6000fd5b505050505060019392505050565b6106d9336109fe565b6106fd5760405163e2c8c9d560e01b81523360048201526024015b60405180910390fd5b81306001600160a01b0382160361071357600080fd5b7f00000000000000000000000000000000000000000000000000000000000000001580159061077457507f00000000000000000000000000000000000000000000000000000000000000008261076860025490565b61077291906116c0565b115b156107a9578161078360025490565b61078d91906116c0565b60405163cbbf111360e01b81526004016106f491815260200190565b6107b38383610c08565b505050565b6107c1336107ec565b6107e05760405163c820b10b60e01b81523360048201526024016106f4565b6107e981610cc7565b50565b6000610504600983610cd1565b610801610cf3565b61080c600982610d48565b156107e9576040516001600160a01b038216907f0a675452746933cefe3d74182e78db7afe57ba60eaa4234b5d85e9aa41b0610c90600090a250565b60006108548383610975565b9392505050565b60606108676007610d5d565b905090565b6006546001600160a01b031633146108bf5760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b60448201526064016106f4565b600580546001600160a01b0319808216339081179093556006805490911690556040516001600160a01b03909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b610923336107ec565b6109425760405163c820b10b60e01b81523360048201526024016106f4565b61094c8282610d6a565b5050565b60606108676009610d5d565b60606004805461051990611670565b61094c828261091a565b600033816109838286610ac1565b9050838110156109e35760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016106f4565b6105cd8286868403610b4c565b6000336105aa818585610be7565b6000610504600783610cd1565b610a13610cf3565b610a1e600782610d7f565b156107e9576040516001600160a01b038216907fe46fef8bbff1389d9010703cf8ebb363fb3daf5bf56edc27080b67bc8d9251ea90600090a250565b610a6381610a0b565b6107e9815b610a70610cf3565b610a7b600982610d7f565b156107e9576040516001600160a01b038216907f92308bb7573b2a3d17ddb868b39d8ebec433f3194421abc22d084f89658c9bad90600090a250565b6107b382826105d8565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610af4610cf3565b6107e981610d94565b610b05610cf3565b610b10600782610d48565b156107e9576040516001600160a01b038216907fed998b960f6340d045f620c119730f7aa7995e7425c2401d3a5b64ff998a59e990600090a250565b81306001600160a01b03821603610b6257600080fd5b610b6d848484610e3e565b50505050565b6000610b7f8484610ac1565b90506000198114610b6d5781811015610bda5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106f4565b610b6d8484848403610b4c565b81306001600160a01b03821603610bfd57600080fd5b610b6d848484610f62565b6001600160a01b038216610c5e5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106f4565b8060026000828254610c7091906116c0565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6107e93382611106565b6001600160a01b03811660009081526001830160205260408120541515610854565b6005546001600160a01b03163314610d465760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b60448201526064016106f4565b565b6000610854836001600160a01b038416611238565b606060006108548361132b565b610d75823383610b73565b61094c8282611106565b6000610854836001600160a01b038416611387565b336001600160a01b03821603610dec5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106f4565b600680546001600160a01b0319166001600160a01b03838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b6001600160a01b038316610ea05760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016106f4565b6001600160a01b038216610f015760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016106f4565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b038316610fc65760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016106f4565b6001600160a01b0382166110285760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016106f4565b6001600160a01b038316600090815260208190526040902054818110156110a05760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016106f4565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610b6d565b6001600160a01b0382166111665760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016106f4565b6001600160a01b038216600090815260208190526040902054818110156111da5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016106f4565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6000818152600183016020526040812054801561132157600061125c600183611724565b855490915060009061127090600190611724565b90508181146112d557600086600001828154811061129057611290611737565b90600052602060002001549050808760000184815481106112b3576112b3611737565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806112e6576112e661174d565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610504565b6000915050610504565b60608160000180548060200260200160405190810160405280929190818152602001828054801561137b57602002820191906000526020600020905b815481526020019060010190808311611367575b50505050509050919050565b60008181526001830160205260408120546113ce57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610504565b506000610504565b6000602082840312156113e857600080fd5b81356001600160e01b03198116811461085457600080fd5b6000815180845260005b818110156114265760208185018101518683018201520161140a565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006108546020830184611400565b80356001600160a01b038116811461147057600080fd5b919050565b6000806040838503121561148857600080fd5b61149183611459565b946020939093013593505050565b6000806000606084860312156114b457600080fd5b6114bd84611459565b92506114cb60208501611459565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b60008060006060848603121561150657600080fd5b61150f84611459565b925060208401359150604084013567ffffffffffffffff8082111561153357600080fd5b818601915086601f83011261154757600080fd5b813581811115611559576115596114db565b604051601f8201601f19908116603f01168101908382118183101715611581576115816114db565b8160405282815289602084870101111561159a57600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b6000602082840312156115ce57600080fd5b5035919050565b6000602082840312156115e757600080fd5b61085482611459565b6020808252825182820181905260009190848201906040850190845b818110156116315783516001600160a01b03168352928401929184019160010161160c565b50909695505050505050565b6000806040838503121561165057600080fd5b61165983611459565b915061166760208401611459565b90509250929050565b600181811c9082168061168457607f821691505b6020821081036116a457634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610504576105046116aa565b8281526040602082015260006116ec6040830184611400565b949350505050565b60018060a01b038416815282602082015260606040820152600061171b6060830184611400565b95945050505050565b81810381811115610504576105046116aa565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fdfea264697066735822122026bf827ff7c4546d08bc173f7cb82c7ccf3be629370907c1d7e2e74f372b4c0164736f6c63430008140033", + "devdoc": { + "details": "The total supply can be limited during deployment.", + "events": { + "Approval(address,address,uint256)": { + "details": "Emitted when the allowance of a `spender` for an `owner` is set by a call to {approve}. `value` is the new allowance." + }, + "Transfer(address,address,uint256)": { + "details": "Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero." + } + }, + "kind": "dev", + "methods": { + "allowance(address,address)": { + "details": "See {IERC20-allowance}." + }, + "approve(address,uint256)": { + "details": "See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address." + }, + "balanceOf(address)": { + "details": "See {IERC20-balanceOf}." + }, + "burn(address,uint256)": { + "details": "Alias for BurnFrom for compatibility with the older naming convention.Uses burnFrom for all validation & logic.", + "params": { + "account": "The address to burn tokens from.", + "amount": "The number of tokens to be burned." + } + }, + "burn(uint256)": { + "details": "Uses OZ ERC20 _burn to disallow burning from address(0).Decreases the total supply." + }, + "burnFrom(address,uint256)": { + "details": "Uses OZ ERC20 _burn to disallow burning from address(0).Decreases the total supply." + }, + "decimals()": { + "details": "Returns the number of decimals used in its user representation." + }, + "decreaseAllowance(address,uint256)": { + "details": "Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`." + }, + "decreaseApproval(address,uint256)": { + "details": "Exists to be backwards compatible with the older naming convention." + }, + "grantBurnRole(address)": { + "details": "only the owner can call this function." + }, + "grantMintAndBurnRoles(address)": { + "details": "calls public functions so this function does not require access controls. This is handled in the inner functions." + }, + "grantMintRole(address)": { + "details": "only the owner can call this function." + }, + "increaseAllowance(address,uint256)": { + "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." + }, + "increaseApproval(address,uint256)": { + "details": "Exists to be backwards compatible with the older naming convention." + }, + "isBurner(address)": { + "returns": { + "_0": "true if the address is allowed to burn." + } + }, + "isMinter(address)": { + "returns": { + "_0": "true if the address is allowed to mint." + } + }, + "maxSupply()": { + "details": "Returns the max supply of the token, 0 if unlimited." + }, + "mint(address,uint256)": { + "details": "Uses OZ ERC20 _mint to disallow minting to address(0).Disallows minting to address(this)Increases the total supply.", + "params": { + "account": "The address to mint the new tokens to.", + "amount": "The number of tokens to be minted." + } + }, + "name()": { + "details": "Returns the name of the token." + }, + "revokeBurnRole(address)": { + "details": "only the owner can call this function" + }, + "revokeMintRole(address)": { + "details": "only the owner can call this function." + }, + "supportsInterface(bytes4)": { + "details": "Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas." + }, + "symbol()": { + "details": "Returns the symbol of the token, usually a shorter version of the name." + }, + "totalSupply()": { + "details": "See {IERC20-totalSupply}." + }, + "transfer(address,uint256)": { + "details": "See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`." + }, + "transferAndCall(address,uint256,bytes)": { + "params": { + "amount": "The amount of tokens to be transferred", + "data": "bytes Additional data with no specified format, sent in call to `to`", + "to": "The address which you want to transfer to" + }, + "returns": { + "success": "true unless throwing" + } + }, + "transferFrom(address,address,uint256)": { + "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`." + } + }, + "stateVariables": { + "i_decimals": { + "details": "The number of decimals for the token" + }, + "i_maxSupply": { + "details": "The maximum supply of the token, 0 if unlimited" + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "acceptOwnership()": { + "notice": "Allows an ownership transfer to be completed by the recipient." + }, + "burn(address,uint256)": { + "notice": "Burns tokens from a given address.." + }, + "getBurners()": { + "notice": "Returns all permissioned burners" + }, + "getMinters()": { + "notice": "Returns all permissioned minters" + }, + "grantBurnRole(address)": { + "notice": "Grants burn role to the given address." + }, + "grantMintAndBurnRoles(address)": { + "notice": "grants both mint and burn roles to `burnAndMinter`." + }, + "grantMintRole(address)": { + "notice": "Grants mint role to the given address." + }, + "isBurner(address)": { + "notice": "Checks whether a given address is a burner for this token." + }, + "isMinter(address)": { + "notice": "Checks whether a given address is a minter for this token." + }, + "mint(address,uint256)": { + "notice": "Mints new tokens for a given address." + }, + "owner()": { + "notice": "Get the current owner" + }, + "revokeBurnRole(address)": { + "notice": "Revokes burn role from the given address." + }, + "revokeMintRole(address)": { + "notice": "Revokes mint role for the given address." + }, + "transferAndCall(address,uint256,bytes)": { + "notice": "Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver" + }, + "transferOwnership(address)": { + "notice": "Allows an owner to begin transferring ownership to a new address, pending." + } + }, + "notice": "A basic ERC677 compatible token contract with burn and minting roles.", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 15, + "contract": "src/LDY.sol:LDY", + "label": "_balances", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 21, + "contract": "src/LDY.sol:LDY", + "label": "_allowances", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 23, + "contract": "src/LDY.sol:LDY", + "label": "_totalSupply", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 25, + "contract": "src/LDY.sol:LDY", + "label": "_name", + "offset": 0, + "slot": "3", + "type": "t_string_storage" + }, + { + "astId": 27, + "contract": "src/LDY.sol:LDY", + "label": "_symbol", + "offset": 0, + "slot": "4", + "type": "t_string_storage" + }, + { + "astId": 2012, + "contract": "src/LDY.sol:LDY", + "label": "s_owner", + "offset": 0, + "slot": "5", + "type": "t_address" + }, + { + "astId": 2014, + "contract": "src/LDY.sol:LDY", + "label": "s_pendingOwner", + "offset": 0, + "slot": "6", + "type": "t_address" + }, + { + "astId": 1444, + "contract": "src/LDY.sol:LDY", + "label": "s_minters", + "offset": 0, + "slot": "7", + "type": "t_struct(AddressSet)1093_storage" + }, + { + "astId": 1447, + "contract": "src/LDY.sol:LDY", + "label": "s_burners", + "offset": 0, + "slot": "9", + "type": "t_struct(AddressSet)1093_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "base": "t_bytes32", + "encoding": "dynamic_array", + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(AddressSet)1093_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.AddressSet", + "members": [ + { + "astId": 1092, + "contract": "src/LDY.sol:LDY", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)778_storage" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Set)778_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 773, + "contract": "src/LDY.sol:LDY", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 777, + "contract": "src/LDY.sol:LDY", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/hardhat/deployments/ethereum/solcInputs/d8b5802e009f6fee7aed14d8582e28a9.json b/hardhat/deployments/ethereum/solcInputs/d8b5802e009f6fee7aed14d8582e28a9.json new file mode 100644 index 0000000..b77ec66 --- /dev/null +++ b/hardhat/deployments/ethereum/solcInputs/d8b5802e009f6fee7aed14d8582e28a9.json @@ -0,0 +1,81 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../../../utils/Context.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20Burnable is Context, ERC20 {\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "src/interfaces/IBurnMintERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface IBurnMintERC20 is IERC20 {\n /// @notice Mints new tokens for a given address.\n /// @param account The address to mint the new tokens to.\n /// @param amount The number of tokens to be minted.\n /// @dev this function increases the total supply.\n function mint(address account, uint256 amount) external;\n\n /// @notice Burns tokens from the sender.\n /// @param amount The number of tokens to be burned.\n /// @dev this function decreases the total supply.\n function burn(uint256 amount) external;\n\n /// @notice Burns tokens from a given address..\n /// @param account The address to burn tokens from.\n /// @param amount The number of tokens to be burned.\n /// @dev this function decreases the total supply.\n function burn(address account, uint256 amount) external;\n\n /// @notice Burns tokens from a given address..\n /// @param account The address to burn tokens from.\n /// @param amount The number of tokens to be burned.\n /// @dev this function decreases the total supply.\n function burnFrom(address account, uint256 amount) external;\n}\n" + }, + "src/interfaces/IERC677.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IERC677 {\n event Transfer(address indexed from, address indexed to, uint256 value, bytes data);\n\n /// @notice Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver\n /// @param to The address which you want to transfer to\n /// @param amount The amount of tokens to be transferred\n /// @param data bytes Additional data with no specified format, sent in call to `to`\n /// @return true unless throwing\n function transferAndCall(address to, uint256 amount, bytes memory data) external returns (bool);\n}\n" + }, + "src/interfaces/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.6;\n\ninterface IERC677Receiver {\n function onTokenTransfer(address sender, uint256 amount, bytes calldata data) external;\n}" + }, + "src/interfaces/IOwnable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IOwnable {\n function owner() external returns (address);\n\n function transferOwnership(address recipient) external;\n\n function acceptOwnership() external;\n}" + }, + "src/LDY.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IBurnMintERC20} from \"./interfaces/IBurnMintERC20.sol\";\nimport {IERC677} from \"./interfaces/IERC677.sol\";\n\nimport {ERC677} from \"./libs/ERC677.sol\";\nimport {OwnerIsCreator} from \"./libs/OwnerIsCreator.sol\";\n\nimport {ERC20Burnable} from \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/**\n * @title LDY\n * @dev The $LDY is the utility and governance token of the entire Ledgity ecosystem.\n *\n * This contract is taken from the official Chainlink CCIP cross-chain token template:\n * https://github.com/smartcontractkit/ccip/blob/onchain-release/v1.1.0/contracts/src/v0.8/shared/token/ERC677/BurnMintERC677.sol\n * \n * No changes have been made to the original contract; only the imports and folder\n * structure have been reworked. This was done to eliminate hundreds of unused files\n * and to import OpenZeppelin libraries directly from their NPM package.\n *\n * $LDY token is non-upgradeable, non-pausable, and non-restrictable.\n *\n * Specs:\n * - Name: Ledgity Token\n * - Symbol: LDY\n * - Decimals: 18\n * - Total supply: 75,000,000\n *\n * @custom:security-contact security@ledgity.com\n */\n\n/// @notice A basic ERC677 compatible token contract with burn and minting roles.\n/// @dev The total supply can be limited during deployment.\ncontract LDY is IBurnMintERC20, ERC677, IERC165, ERC20Burnable, OwnerIsCreator {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n error SenderNotMinter(address sender);\n error SenderNotBurner(address sender);\n error MaxSupplyExceeded(uint256 supplyAfterMint);\n\n event MintAccessGranted(address indexed minter);\n event BurnAccessGranted(address indexed burner);\n event MintAccessRevoked(address indexed minter);\n event BurnAccessRevoked(address indexed burner);\n\n // @dev the allowed minter addresses\n EnumerableSet.AddressSet internal s_minters;\n // @dev the allowed burner addresses\n EnumerableSet.AddressSet internal s_burners;\n\n /// @dev The number of decimals for the token\n uint8 internal immutable i_decimals;\n\n /// @dev The maximum supply of the token, 0 if unlimited\n uint256 internal immutable i_maxSupply;\n\n constructor(string memory name, string memory symbol, uint8 decimals_, uint256 maxSupply_) ERC677(name, symbol) {\n i_decimals = decimals_;\n i_maxSupply = maxSupply_;\n }\n\n function supportsInterface(bytes4 interfaceId) public pure virtual override returns (bool) {\n return\n interfaceId == type(IERC20).interfaceId ||\n interfaceId == type(IERC677).interfaceId ||\n interfaceId == type(IBurnMintERC20).interfaceId ||\n interfaceId == type(IERC165).interfaceId;\n }\n\n // ================================================================\n // | ERC20 |\n // ================================================================\n\n /// @dev Returns the number of decimals used in its user representation.\n function decimals() public view virtual override returns (uint8) {\n return i_decimals;\n }\n\n /// @dev Returns the max supply of the token, 0 if unlimited.\n function maxSupply() public view virtual returns (uint256) {\n return i_maxSupply;\n }\n\n /// @dev Uses OZ ERC20 _transfer to disallow sending to address(0).\n /// @dev Disallows sending to address(this)\n function _transfer(address from, address to, uint256 amount) internal virtual override validAddress(to) {\n super._transfer(from, to, amount);\n }\n\n /// @dev Uses OZ ERC20 _approve to disallow approving for address(0).\n /// @dev Disallows approving for address(this)\n function _approve(address owner, address spender, uint256 amount) internal virtual override validAddress(spender) {\n super._approve(owner, spender, amount);\n }\n\n /// @dev Exists to be backwards compatible with the older naming convention.\n function decreaseApproval(address spender, uint256 subtractedValue) external returns (bool success) {\n return decreaseAllowance(spender, subtractedValue);\n }\n\n /// @dev Exists to be backwards compatible with the older naming convention.\n function increaseApproval(address spender, uint256 addedValue) external {\n increaseAllowance(spender, addedValue);\n }\n\n /// @notice Check if recipient is valid (not this contract address).\n /// @param recipient the account we transfer/approve to.\n /// @dev Reverts with an empty revert to be compatible with the existing link token when\n /// the recipient is this contract address.\n modifier validAddress(address recipient) virtual {\n // solhint-disable-next-line reason-string, custom-errors\n if (recipient == address(this)) revert();\n _;\n }\n\n // ================================================================\n // | Burning & minting |\n // ================================================================\n\n /// @inheritdoc ERC20Burnable\n /// @dev Uses OZ ERC20 _burn to disallow burning from address(0).\n /// @dev Decreases the total supply.\n function burn(uint256 amount) public override(IBurnMintERC20, ERC20Burnable) onlyBurner {\n super.burn(amount);\n }\n\n /// @inheritdoc IBurnMintERC20\n /// @dev Alias for BurnFrom for compatibility with the older naming convention.\n /// @dev Uses burnFrom for all validation & logic.\n function burn(address account, uint256 amount) public virtual override {\n burnFrom(account, amount);\n }\n\n /// @inheritdoc ERC20Burnable\n /// @dev Uses OZ ERC20 _burn to disallow burning from address(0).\n /// @dev Decreases the total supply.\n function burnFrom(address account, uint256 amount) public override(IBurnMintERC20, ERC20Burnable) onlyBurner {\n super.burnFrom(account, amount);\n }\n\n /// @inheritdoc IBurnMintERC20\n /// @dev Uses OZ ERC20 _mint to disallow minting to address(0).\n /// @dev Disallows minting to address(this)\n /// @dev Increases the total supply.\n function mint(address account, uint256 amount) external override onlyMinter validAddress(account) {\n if (i_maxSupply != 0 && totalSupply() + amount > i_maxSupply) revert MaxSupplyExceeded(totalSupply() + amount);\n\n _mint(account, amount);\n }\n\n // ================================================================\n // | Roles |\n // ================================================================\n\n /// @notice grants both mint and burn roles to `burnAndMinter`.\n /// @dev calls public functions so this function does not require\n /// access controls. This is handled in the inner functions.\n function grantMintAndBurnRoles(address burnAndMinter) external {\n grantMintRole(burnAndMinter);\n grantBurnRole(burnAndMinter);\n }\n\n /// @notice Grants mint role to the given address.\n /// @dev only the owner can call this function.\n function grantMintRole(address minter) public onlyOwner {\n if (s_minters.add(minter)) {\n emit MintAccessGranted(minter);\n }\n }\n\n /// @notice Grants burn role to the given address.\n /// @dev only the owner can call this function.\n function grantBurnRole(address burner) public onlyOwner {\n if (s_burners.add(burner)) {\n emit BurnAccessGranted(burner);\n }\n }\n\n /// @notice Revokes mint role for the given address.\n /// @dev only the owner can call this function.\n function revokeMintRole(address minter) public onlyOwner {\n if (s_minters.remove(minter)) {\n emit MintAccessRevoked(minter);\n }\n }\n\n /// @notice Revokes burn role from the given address.\n /// @dev only the owner can call this function\n function revokeBurnRole(address burner) public onlyOwner {\n if (s_burners.remove(burner)) {\n emit BurnAccessRevoked(burner);\n }\n }\n\n /// @notice Returns all permissioned minters\n function getMinters() public view returns (address[] memory) {\n return s_minters.values();\n }\n\n /// @notice Returns all permissioned burners\n function getBurners() public view returns (address[] memory) {\n return s_burners.values();\n }\n\n // ================================================================\n // | Access |\n // ================================================================\n\n /// @notice Checks whether a given address is a minter for this token.\n /// @return true if the address is allowed to mint.\n function isMinter(address minter) public view returns (bool) {\n return s_minters.contains(minter);\n }\n\n /// @notice Checks whether a given address is a burner for this token.\n /// @return true if the address is allowed to burn.\n function isBurner(address burner) public view returns (bool) {\n return s_burners.contains(burner);\n }\n\n /// @notice Checks whether the msg.sender is a permissioned minter for this token\n /// @dev Reverts with a SenderNotMinter if the check fails\n modifier onlyMinter() {\n if (!isMinter(msg.sender)) revert SenderNotMinter(msg.sender);\n _;\n }\n\n /// @notice Checks whether the msg.sender is a permissioned burner for this token\n /// @dev Reverts with a SenderNotBurner if the check fails\n modifier onlyBurner() {\n if (!isBurner(msg.sender)) revert SenderNotBurner(msg.sender);\n _;\n }\n}\n" + }, + "src/libs/ConfirmedOwner.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./ConfirmedOwnerWithProposal.sol\";\n\n/**\n * @title The ConfirmedOwner contract\n * @notice A contract with helpers for basic contract ownership.\n */\ncontract ConfirmedOwner is ConfirmedOwnerWithProposal {\n constructor(address newOwner) ConfirmedOwnerWithProposal(newOwner, address(0)) {}\n}" + }, + "src/libs/ConfirmedOwnerWithProposal.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"../interfaces/IOwnable.sol\";\n\n/**\n * @title The ConfirmedOwner contract\n * @notice A contract with helpers for basic contract ownership.\n */\ncontract ConfirmedOwnerWithProposal is IOwnable {\n address private s_owner;\n address private s_pendingOwner;\n\n event OwnershipTransferRequested(address indexed from, address indexed to);\n event OwnershipTransferred(address indexed from, address indexed to);\n\n constructor(address newOwner, address pendingOwner) {\n require(newOwner != address(0), \"Cannot set owner to zero\");\n\n s_owner = newOwner;\n if (pendingOwner != address(0)) {\n _transferOwnership(pendingOwner);\n }\n }\n\n /**\n * @notice Allows an owner to begin transferring ownership to a new address,\n * pending.\n */\n function transferOwnership(address to) public override onlyOwner {\n _transferOwnership(to);\n }\n\n /**\n * @notice Allows an ownership transfer to be completed by the recipient.\n */\n function acceptOwnership() external override {\n require(msg.sender == s_pendingOwner, \"Must be proposed owner\");\n\n address oldOwner = s_owner;\n s_owner = msg.sender;\n s_pendingOwner = address(0);\n\n emit OwnershipTransferred(oldOwner, msg.sender);\n }\n\n /**\n * @notice Get the current owner\n */\n function owner() public view override returns (address) {\n return s_owner;\n }\n\n /**\n * @notice validate, transfer ownership, and emit relevant events\n */\n function _transferOwnership(address to) private {\n require(to != msg.sender, \"Cannot transfer to self\");\n\n s_pendingOwner = to;\n\n emit OwnershipTransferRequested(s_owner, to);\n }\n\n /**\n * @notice validate access\n */\n function _validateOwnership() internal view {\n require(msg.sender == s_owner, \"Only callable by owner\");\n }\n\n /**\n * @notice Reverts if called by anyone other than the contract owner.\n */\n modifier onlyOwner() {\n _validateOwnership();\n _;\n }\n}" + }, + "src/libs/ERC677.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IERC677} from \"../interfaces/IERC677.sol\";\nimport {IERC677Receiver} from \"../interfaces/IERC677Receiver.sol\";\n\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract ERC677 is IERC677, ERC20 {\n constructor(string memory name, string memory symbol) ERC20(name, symbol) {}\n\n /// @inheritdoc IERC677\n function transferAndCall(address to, uint256 amount, bytes memory data) public returns (bool success) {\n super.transfer(to, amount);\n emit Transfer(msg.sender, to, amount, data);\n if (to.code.length > 0) {\n IERC677Receiver(to).onTokenTransfer(msg.sender, amount, data);\n }\n return true;\n }\n}\n" + }, + "src/libs/OwnerIsCreator.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ConfirmedOwner} from \"./ConfirmedOwner.sol\";\n\n/// @title The OwnerIsCreator contract\n/// @notice A contract with helpers for basic contract ownership.\ncontract OwnerIsCreator is ConfirmedOwner {\n constructor() ConfirmedOwner(msg.sender) {}\n}\n" + } + }, + "settings": { + "evmVersion": "london", + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/src/LDY.sol b/src/LDY.sol index 8a9bd29..ce6900a 100644 --- a/src/LDY.sol +++ b/src/LDY.sol @@ -36,7 +36,7 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; /// @notice A basic ERC677 compatible token contract with burn and minting roles. /// @dev The total supply can be limited during deployment. -contract TSTTOKEN is IBurnMintERC20, ERC677, IERC165, ERC20Burnable, OwnerIsCreator { +contract LDY is IBurnMintERC20, ERC677, IERC165, ERC20Burnable, OwnerIsCreator { using EnumerableSet for EnumerableSet.AddressSet; error SenderNotMinter(address sender);